home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-11-22 | 152.7 KB | 4,214 lines |
- *----------------------------------------------------------------------
- *-- Program...: FILES.PRG
- *-- Programmer: Ken Mayer (CIS: 71333,1030)
- *-- Date......: 08/02/1993
- *-- Notes.....: These are file processing routines. To see how to use
- *-- this library file, see: README.TXT.
- *----------------------------------------------------------------------
-
- PROCEDURE AllTags
- *----------------------------------------------------------------------
- *-- Programmer..: Susan Perschke (SPECDATA)/Michael Liczbanski (LMIKE)
- *-- Date........: 01/03/1992
- *-- Notes.......: Used to bring up a list of MDX tags on screen for the
- *-- user, so they can change the current tag ... This was
- *-- gotten to me by Steve (LTI), from "Data Based
- *-- Advisor", December, 1991.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 12/15/1991 - original procedure.
- *-- 01/03/1992 - Ken Mayer -- added shadow ...
- *-- Calls.......: SHADOW Procedure in PROC.PRG
- *-- Called by...: Any
- *-- Usage.......: DO AllTags WITH nULRow, nULCol
- *-- Example.....: ON KEY LABEL F8 DO ALLTAGS WITH 02,60
- *-- Returns.....: None
- *-- Parameters..: nULRow -- Starting Row for Popup
- *-- nULCol -- Starting Column for Popup
- *----------------------------------------------------------------------
-
- parameters nULRow, nULCol
- private nBar, cPrompt, nBRRow, nBRCol
-
- *-- Disable left/right arrow keys to prevent an accidental exit
- on key label leftarrow ?? chr(7)
- on key label rightarrow ?? chr(7)
-
- *-- Save current screen
- save screen to sTag
- activate screen
-
- *-- define the popup
- define popup pTag from m->nULRow, m->nULCol;
- message " Press ENTER to select new index order...ESC to exit..."
- nBar = 1 && first bar
- cPrompt = "-No Index-" && will always be this
-
- *-- loop to get the rest of 'em ...
- do while "" <> m->cPrompt && loop until no more tags
- define bar nBar of pTag prompt (m->cPrompt)
- cPrompt = tag(m->nBar)
- nBar = m->nBar + 1
- enddo
-
- on selection popup pTag deactivate popup
-
- *-- process shadow
- nBRRow = m->nULRow + (m->nBar - 1) + 1
- && bottom right for shadow (+1 for top, bottom)
- nBRCol = m->nULCol + 11
- && bottom right for shadow (+2 for sides, +9 for tagnames)
- do shadow with m->nULRow, m->nULCol, m->nBRRow, m->nBRCol
-
- *-- do it
- activate popup pTag
-
- *-- Assign a null string to cPrompt if "No Index" selected
- cPrompt = iif(bar() = 1, "",prompt())
-
- *-- Don't change index order if ESC pressed
- if bar() <> 0
- set order to (m->cPrompt)
- endif
-
- *-- cleanup
- release popup pTag
- restore screen from sTag
- release screen sTag
-
- *-- Enable left/right arrow keys
- on key label leftarrow
- on key label rightarrow
-
- RETURN
- *-- EoP: AllTags
-
- PROCEDURE MakeTagFl
- *----------------------------------------------------------------------
- *-- Programmer..: Bowen Moursund (CIS: 72662,436)
- *-- Date........: 04/15/1992
- *-- Notes.......: Build a .dbf file from scratch, without using CREATE
- *-- FROM. The file built has three fields, TAGS1, TAGS2
- *-- and TAGS3, each character-type and 254 bytes wide.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: Broken out of other code and date-writing added
- *-- by Jay Parsons, 4/15/1992
- *-- Originally from the program PRGCREAT.ZIP
- *-- Called by...: Any
- *-- Usage.......: do MakeTagFl WITH "<cFname>"
- *-- Example.....: do MakeTagFl WITH "Tags"
- *-- Returns.....: None
- *-- Parameters..: cFname, name of the .dbf to create
- *-- Side effects: Creates a .DBF. Overwrites existing .DBF of same name
- *-- Disables external setting of PRINTER
- *----------------------------------------------------------------------
-
- parameters cFname
- private cName
- cName = m->cFname
- if .not. "." $ m->cName
- cName = m->cName + ".DBF"
- endif
- set printer to file ( m->cName )
- set printer on
- ??? "{3}"
- ??? chr( year( date() - 1900 ) )
- ??? chr( month( date() ) )
- ??? chr( day( date() ) )
- ??? "{0}{0}{0}{0}{129}{0}{251}{2}{0}{0}{0}{0}"
- ??? "{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{201}{0}" && Tags1
- ??? "{84}{65}{71}{83}{49}{0}{0}{0}{0}{0}{0}{67}{0}{0}{0}{0}"
- ??? "{254}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}" && Tags2
- ??? "{84}{65}{71}{83}{50}{0}{0}{0}{0}{0}{0}{67}{0}{0}{0}{0}"
- ??? "{254}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}" && Tags3
- ??? "{84}{65}{71}{83}{51}{0}{0}{0}{0}{0}{0}{67}{0}{0}{0}{0}"
- ??? "{254}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"
- ??? "{13}{26}"
- set printer off
- set printer to
-
- RETURN
- *-- EoP: MakeTagFl
-
- PROCEDURE RedoTags
- *----------------------------------------------------------------------
- *-- Programmer..: David Love (CIS: 70153,2433)
- *-- Date........: 04/18/1992
- *-- Notes.......: This routine is a "generic" MDX cleanup routine. It
- *-- is useful for handling "bloated" MDX files -- ones
- *-- that have been around awhile (they tend to be larger
- *-- than necessary). This routine will store the tag keys
- *-- in an array, delete the tags, and then rebuild the
- *-- MDX file from scratch, keeping all tag names and
- *-- keys, and the MDX SHOULD be smaller.
- *-- Will act on production mdx (ie. same name as dbf)
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 01/20/1992 - original function for dBASE IV Ver. 1.1.
- *-- 04/18/1992 - David Love - adapted for use with beta
- *-- version of dBASE IV, version 1.5.
- *-- (TAGCOUNT(), FOR(), DESCENDING(), UNIQUE() are 1.5
- *-- functions)
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: do RedoTags with "<cDBF>"
- *-- Example.....: do RedoTags with "Referral"
- *-- Returns.....: None
- *-- Parameters..: cDBF = Name of DATABASE file, no extension necessary.
- *----------------------------------------------------------------------
-
- parameter cDBF
-
- use (cDBF) excl
-
- *-- First, figure out how many tags exist
-
- private nMaxTags
- nMaxTags = tagcount( m->cDBF, 1 )
-
- *-- only perform routine if an index tag exists
- if m->nMaxTags > 0
- private nTags, mkey, mtag
-
- *-- store the keys and tags to an array
- declare aTags[m->nMaxTags,5]
- nTags = 1
- do while nTags <= m->nMaxTags
- && grab key
- store key( (m->cDBF),m->nTags) to aTags[m->nTags,1]
- && grab tagname
- store tag( (m->cDBF),m->nTags) to aTags[m->nTags,2]
- && grab for clause
- store for( (m->cDBF),m->nTags) to aTags[m->nTags,3]
- && .t. =descending
- store descending( (m->cDBF),m->nTags) to aTags[m->nTags,4]
- && .t. =unique
- store unique( (m->cDBF),m->nTags) to aTags[m->nTags,5]
- nTags = nTags + 1
- enddo
-
- *-- now, delete the tags
- do while "" # tag( (m->cDBF),1)
- delete tag tag( (m->cDBF), 1)
- enddo
-
- *-- rebuild the MDX, tag by tag ...
- nTags = 1
- do while nTags <= nMaxTags
- mkey = aTags[m->nTags,1]+iif(""#aTags[m->nTags,3]," ;
- for "+aTags[m->nTags,3],"") ;
- + iif(aTags[m->nTags,4]," DESCENDING","") ;
- + iif(aTags[m->nTags,5]," UNIQUE","")
- mtag = aTags[m->nTags,2]
- index on &mkey. tag &mtag.
- nTags = m->nTags + 1
- enddo
-
- *-- release the array ...
- release aTags
-
- endif && check for tags ...
- use && close database
-
- RETURN
- *-- EoP: RedoTags
-
- PROCEDURE AutoRedo
- *---------------------------------------------------------------------
- *-- Programmer..: Douglas P. Saine (CIS: 74660,3574)
- *-- Date........: 03/06/1992
- *-- Notes.......: Displays a popup to choose a DBF from the current
- *-- directory to re-build its MDX file
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/04/1992 - original procedure.
- *-- 03/06/1992 -- Ken Mayer added color parameter,
- *-- shadow to popup, and erase DBFS.DBF datafile at end.
- *-- Calls.......: LISTDBFS Procedure in FILES.PRG
- *-- REDOTAGS Procedure in FILES.PRG
- *-- CENTER Procedure in PROC.PRG
- *-- YESNO2() Function in PROC.PRG
- *-- SHADOW Procedure in PROC.PRG
- *-- EXTRCLR() Function in PROC.PRG
- *-- Called by...: Any
- *-- Usage.......: do AutoRedo with nXTL,nYTL,nXBR,nYBR,cColor
- *-- Example.....: do AutoRedo with 5,34,15,47,"rg+/gb,w+/n,rg+/gb"
- *-- Returns.....: None
- *-- Parameters..: None
- *---------------------------------------------------------------------
-
- parameters nXTL, nYTL, nXBR, nYBR, cColor
-
- *-- Save Environment
- cTalk = set("talk")
- cStat = set("status")
- cCloc = set("clock")
- cScor = set("scoreboard")
- cSafe = set("safety")
-
- *-- Set Environment
- set stat off
- set talk off
- set cloc off
- set scor off
- set safe off
-
- *-- Full Screen Window for screen restoration when finished
- define window wCoverScr from 0,0 to 23,79 none
- activate window wCoverScr
- clear
-
- *-- Make a Data File of the Current Directory
- do center with 10,80,extrclr(m->cColor),;
- '... Making Data File from Current Directory ...'
- do ListDBFs
-
- use DBFS
- index on DBFS->DBF tag IORDER
-
- *-- Define and access the popup of DataFiles
- activate screen
- define popup uDbfList from m->nXTL,m->nYTL to m->nXBR,m->nYBR ;
- prompt field DBFS->DBF
- on selection popup uDbfList deactivate popup
-
- *-- Execute loop for multiple re-indexes
- clear
- lLoop = .t.
- do while m->lLoop
- do shadow with m->nXTL,m->nYTL,m->nXBR,m->nYBR
- activate popup uDbfList
- clear && get rid of shadow
-
- *-- Record prompt() and remove '.dbf' so it works with Redotag
- cDataFile = substr(prompt(),1,len(trim(prompt()))-4)
-
- *-- Verify the MDX exists
- if file(m->cDataFile+'.mdx')
- do redotags with m->cDataFile
- else
- do center with 10,80,extrclr(m->cColor),;
- '... Production MDX file not found for file '+m->cDataFile
- n = inkey(0)
- clear
- endif
-
- *-- Determine if the user wants to re-build another
- if YesNo2(.t.,"CC","",;
- "Do you wish to reindex another file?","",m->cColor)
- use DBFS order IORDER
- else
- lLoop = .f.
- endif
-
- enddo
-
- *-- Restore environment
- use DBFS
- delete tag IORDER
- use
- erase DBFS.DBF
- release popup uDbfList
- deactivate window wCoverScr
- release window wCoverScr
- set stat &cStat.
- set talk &cTalk.
- set cloc &cCloc.
- set scor &cScor.
- set safe &cSafe.
-
- RETURN
- *-- EoP: AutoRedo
-
- PROCEDURE PrntTags
- *----------------------------------------------------------------------
- *-- Programmer..: David Love (CIS: 70153,2433)
- *-- Date........: 03/24/1993
- *-- Notes.......: This routine is a "quick and not-so-dirty" method of
- *-- printing the tag and key expressions for a dbf's
- *-- production mdx file. It obviates the need for DISP or
- *-- LIST STAT TO PRINT (or DISP STAT with SHIFT+PrtScr).
- *-- This code is modified from the procedure RedoTags,
- *-- previously posted on the BORBBS.
- *-- : The proc will print the full key expression,
- *-- including FOR/DESCENDING/UNIQUE options, if present.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 01/31/1992 - original procedure for dBASE IV, Ver 1.1
- *-- 04/18/1992 - David Love - revised for version 1.5
- *-- 03/24/1993 - Lee Hite - modified so that wild card
- *-- specs may now be used to list multiple
- *-- .DBF's. also, added optional parameter
- *-- to include file structure in output.
- *-- Calls.......: ADIR() Function in FILES.PRG
- *-- PARSPATH() Function in FILES.PRG
- *-- SHELLSORT() Function in ARRAY.PRG
- *-- NOTE: These are called only when using wildcards.
- *-- Called by...: Any
- *-- Usage.......: do PrntTags with "<cDBF>",[lDispStru]
- *-- Example.....: do PrntTags with "Referral"
- *-- do PrntTags with "*.dbf",.t.
- *-- Returns.....: None
- *-- Parameters..: cDBF = Name of DATABASE file, may include
- *-- wildcard specs(i.e., "REF*"). No
- *-- extension is necessary, but if it's
- *-- there, it better be ".DBF" <g>
- *-- lDispStru = [optional] set to .T. to include the file
- *-- structure in the output
- *----------------------------------------------------------------------
-
- parameter cDBFParm,lDispStru
-
- private cTalk
- cTalk = set("TALK")
- set talk off
- set printer on
-
- *-- handle whether or not we got a wild card
- private cDBFPath,cDBFMask,nDBFs,aMyArray,lDummy,nKntr
- if "*" $ m->cDBFParm .or. "?" $ m->cDBFParm
- *-- wildcards, so build an array of the file names
- cDBFMask = iif(at(".DBF",upper(m->cDBFParm))>0,;
- m->cDBFParm, m->cDBFParm+".DBF")
- nDBFs = aDir(m->cDBFMask,"","")
- if nDBFs > 0
- declare aMyArray[m->nDBFs,1]
- nKntr = 1
- do while m->nKntr <= m->nDBFs
- aMyArray[m->nKntr,1] = gaDir[m->nKntr,1]
- nKntr = m->nKntr + 1
- enddo
- lDummy = ShellSort(m->nDBFs)
- endif
- cDBFPath = ParsPath(m->cDBFMask)
- else
- *-- no wild cards, so we just have one entry in the array
- private aMyArray
- declare aMyArray[1,1]
- aMyArray[1,1] = upper(m->cDBFParm)
- nDBFs = 1
- cDBFPath = ""
- endif
-
- *-- loop for each .DBF
- private cDBF,nKntr
- nKntr = 1
- do while m->nKntr <= m->nDBFs
- cDBF = aMyArray[m->nKntr,1]
- *-- pull extension out of file name so TAGCOUNT(), etc. work...
- cDBF = iif(at(".DBF",m->cDBF)=0,m->cDBF,;
- left(m->cDBF,at(".DBF",m->cDBF)-1))
- use (cDBFPath+cDBF)
- ?? "DATABASE: "+m->cDBF at 0
- ?
- ?
-
- *-- display file structure if optioned
- if lDispStru
- ?? "STRUCTURE:" at 0
- disp stru
- ?
- endif
-
- *-- now, figure out how many tags exist
- private nMaxTags
- nMaxTags = tagcount( m->cDBF )
- ?? "INDEX TAGS:" at 0
- ?
-
- *-- only perform routine if an index tag exists
- if m->nMaxTags > 0
- private nTags, mkey, mtag
-
- *-- store the keys and tags to an array
- declare aTags[m->nMaxTags,5]
- nTags = 1
- do while m->nTags <= m->nMaxTags
- * grab the key
- store key( (m->cDBF),m->nTags) to aTags[m->nTags,1]
- * grab the tagname
- store tag( (m->cDBF),m->nTags) to aTags[m->nTags,2]
- * grab the for clause
- store for( (m->cDBF),m->nTags) to aTags[m->nTags,3]
- * .t. if descending
- store descending( (m->cDBF),m->nTags) to aTags[m->nTags,4]
- * .t. if unique
- store unique( (m->cDBF),m->nTags) to aTags[m->nTags,5]
- nTags = m->nTags + 1
- enddo
-
- *-- print each tag with it's key expression
- ?? "Tag" at 0
- ?? "Key Expression" AT 12
- ?
- nTags = 1
- do while m->nTags <= m->nMaxTags
- ?? aTags[m->nTags,2] AT 0
- ?? aTags[m->nTags,1] + ;
- iif(""#aTags[m->nTags,3]," FOR "+aTags[m->nTags,3],"") +;
- iif(aTags[m->nTags,4]," DESCENDING","") + ;
- iif(aTags[m->nTags,5]," UNIQUE","") AT 12
- ?
- nTags = m->nTags + 1
- enddo
-
- *-- release the array ...
- release aTags
-
- else
- *-- no tags found
- ?? "none" at 0
- ?
- endif && check for tags ...
- use && close database
- ?? replicate("=",60) at 0
- ?
- nKntr = m->nKntr + 1
-
- enddo && loop for each .dbf
-
- *-- restore the environment
- release gaDir
- set printer off
- set talk &cTalk.
-
- RETURN
- *-- EoP: PrntTags
-
- PROCEDURE ListDBFs
- *----------------------------------------------------------------------
- *-- Programmer..: David Love (70153,2433)
- *-- Date........: 01/31/1992
- *-- Notes.......: This procedure will create a list of the database
- *-- (.dbf) files in the current directory. It will
- *-- create a database file named Dbfs.dbf which exists
- *-- of one 12-character field--Dbf. It will also create
- *-- a text file, Dbfs.txt, through the LIST FILES to FILE
- *-- command. Then it will append records to the Dbfs.dbf
- *-- file and erase the Dbfs.txt file.
- *-- This Dbfs.dbf file can be SCANned, or used in a POPUP
- *-- PROMPT FIELD command, or in any other way imaginable.
- *-- The file 'Dbfs.dbf' will not be included in the
- *-- Dbfs.dbf file.
- *-- WARNING===> If your application includes a file with the name of
- *-- 'Dbfs.dbf', it will be overwritten with the file
- *-- created by this procedure.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 01/31/1992 -- Original
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: do ListDBFs
- *-- Example.....: do ListDBFs
- *-- Returns.....: None
- *-- Parameters..: None
- *----------------------------------------------------------------------
-
- private cConsole
- *-- Write the directory of dbf files to a text file (Dbfs.txt)
- *-- First, erase the file if it exists
- if file("Dbfs.txt")
- erase dbfs.txt
- endif
-
- *-- And, erase the dbfs.dbf file if it exists (so won't be included
- *-- in the list)
- if file("Dbfs.dbf")
- erase Dbfs.dbf
- endif
-
- *-- Now, write the dbfs.txt file
- cConsole = set("CONSOLE")
- set console off
- list files to file dbfs.txt
- set console &cConsole.
-
- *-- Then, create the file DBFS.DBF
- *-- Acknowledgement..: Bowen Moursund for code that creates Dbfs.dbf
- set printer to file DBFS.DBF
- set printer on
- ??? "{3}{92}{2}{1}{0}{0}{0}{0}{65}{0}{13}{0}{0}{0}{0}{0}{0}{0}"+;
- "{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{89}{0}{68}{66}{70}{0}{0}"+;
- "{0}{0}{0}{0}{0}{0}{67}{3}{0}{44}{85}{12}{0}{0}{0}{1}{0}{0}{0}"+;
- "{0}{0}{0}{0}{0}{0}{0}{0}{13}{26}"
- set printer to
- set printer off
-
- *-- Now, append dbfs.txt to dbfs.dbf if the record is a dbf listing.
- use Dbfs
- append from Dbfs.txt for ".DBF" $ Dbf type sdf
-
- use && can remove this command if you want
-
- erase Dbfs.txt && don't need it anymore
-
- RETURN
- *--EOP: ListDBFs
-
- FUNCTION Recompile
- *----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Adapted from Compall.prg/Compall2.prg by James Thomas
- *-- Date........: 06/10/1992
- *-- Notes.......: Recompiles all dBASE source-code files. Takes three
- *-- optional parameters:
- *-- Directory to recompile. Default is current directory.
- *-- Skeleton to recompile. Default is all of .PRG, .LBG,
- *-- .FRG, .PRS, .FMT, .QBE and .UPD files. If a skeleton
- *-- is provided that matches files that are not dBASE
- *-- source-code files, compiler errors will occur and,
- *-- in the absence of external error handling, see below,
- *-- suspend processing.
- *-- "Runtime" or any characters starting with "R" or "r"
- *-- to direct that compilation use the "RUNTIME" option.
- *-- Does not recompile a file if a file of the same root
- *-- name, an .??O extension and a later timestamp resides
- *-- in the directory.
- *-- Renames compilations of FMT, FRG, LBG and QBO files
- *-- to ??O.
- *-- Returns .T. if successful, or .F.
- *--
- *-- Listing of compilation errors requires SET ALTERNATE
- *-- TO, and trapping such errors as passing the name of a
- *-- file that does not contain dBASE source code to the
- *-- COMPILE command requires an ON ERROR trap. These are
- *-- omitted here due to lack of ways to prevent the
- *-- function from changing these settings externally.
- *-- Lines needed to have any compilation errors print to
- *-- the alternate file are included as comments.
- *-- Written for.: dBASE IV Version 1.5.
- *-- Adaptation for 1.1 may require changing the way
- *-- parameters are handled, and also rewriting the lines
- *-- that use fdate() and ftime() to read timestamps.
- *-- Rev. History: 04/07/1992 - original function.
- *-- 04/13/1992 - additional environment settings.
- *-- 04/16/1992 - aliases added thanks to BOWEN.
- *-- 06/10/1992 - a few minor bug fixes
- *-- 08/02/1993 - references to cDir corrected
- *-- Calls.......: Makestru() FUNCTION in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: Recompile ( [<cDir>] [,<cSkel> [,"R"]] )
- *-- Example.....: ? Recompile ( "\dBASE\Myprogs", "*.??G" )
- *-- Parameters..: cDir, a DOS directory name ( and path if needed )
- *-- cSkel, skeleton using wildcards for files to compile
- *-- cRun, "R" or "r" if compilation is for Runtime
- *-- Side effects: Creates compiled .??O files, overwriting any of the
- *-- same root names that may exist.
- *----------------------------------------------------------------------
-
- parameters cDirectry, cSkeleton, cRun
- private cCons, cAlias, cAlt, cDir, cSafety, cTempfile,;
- cSrcfile, cObjfile, cString1, cString2, cRunopt
-
- * preserve environment
- cCons = set( "CONSOLE" )
- SET CONSOLE OFF
- cAlias = alias()
- cAlt = set( "ALTERNATE" )
- SET ALTERNATE OFF
- cDir = set( "DIRECTORY" )
- IF type( "cDir" ) = "C" .AND. "" # cDir
- SET DIRECTORY TO &cDir.
- ENDIF
- cSafety = set( "SAFETY" )
- SET SAFETY OFF
- SELECT select()
-
- * make temporary structure file & fill in the DOS DIR listing struc
- cTempfile = Makestru()
- USE ( cTempfile ) ALIAS cTempfile
- APPEND BLANK
- REPLACE FIELD_NAME WITH "FILENAME", FIELD_TYPE WITH "C", ;
- FIELD_LEN WITH 9, FIELD_DEC WITH 0, FIELD_IDX WITH "N"
- APPEND BLANK
- REPLACE FIELD_NAME WITH "EXT", FIELD_TYPE WITH "C", ;
- FIELD_LEN WITH 4, FIELD_DEC WITH 0, FIELD_IDX WITH "N"
- APPEND BLANK
- REPLACE FIELD_NAME WITH "FLENGTH", FIELD_TYPE WITH "C", ;
- FIELD_LEN WITH 10, FIELD_DEC WITH 0, FIELD_IDX WITH "N"
- APPEND BLANK
- REPLACE FIELD_NAME WITH "TIMESTAMP", FIELD_TYPE WITH "C", ;
- FIELD_LEN WITH 16, FIELD_DEC WITH 0, FIELD_IDX WITH "N"
-
- * make .dbf for source file names, reset and return if error occurs
- cSrcfile = m->cTempfile
- DO WHILE file ( m->cSrcfile + ".DBF" )
- cSrcfile = "TMP" + ltrim( str( rand() * 100000, 5 ) )
- ENDDO
- CREATE ( cSrcfile ) FROM ( cTempfile )
- USE ( cSrcfile ) alias cSrcfile
-
- IF "" = alias()
- ERASE ( m->cTempfile +".DBF" )
- SET DIRECTORY TO &cDir.
- SET ALTERNATE &cAlt.
- IF "" # m->cAlias
- SELECT ( cAlias )
- ENDIF
- SET CONSOLE &cCons.
- RETURN .F.
- ENDIF
-
- * and for object file names
- SELECT select()
- USE ( cTempfile ) ALIAS cTempfile
- GO 1
- REPLACE FIELD_IDX WITH "Y"
- cObjfile = m->cSrcfile
- DO WHILE file ( m->cObjfile + ".DBF" )
- cObjfile = "TMP" + ltrim( str( rand() * 100000, 5 ) )
- ENDDO
- CREATE ( cObjfile ) FROM (cTempfile)
- use ( cObjfile ) alias cObjfile order filename
- IF "" = alias()
- ERASE ( m->cTempfile + ".DBF" )
- SELECT cSrcfile
- USE
- ERASE ( m->cSrcfile + ".DBF" )
- SET DIRECTORY TO &cDir.
- SET ALTERNATE &cAlt.
- IF "" # cAlias
- SELECT ( m->cAlias )
- ENDIF
- SET CONSOLE &cCons.
- RETURN .F.
- ENDIF
-
- * reuse name of cTempfile as SDF
- cString1 = m->cTempfile + ".DBF"
-
- * DIR names of source files to it and append
- RUN dir *.* > &cString1.
- SELECT cSrcfile
- APPEND FROM ( cString1 ) TYPE SDF
-
- * delete unwanted directory entries
- IF type("cSkeleton") = "C" .AND. "" # m->cSkeleton
- DELETE ALL FOR .NOT. like( upper( m->cSkeleton ), ;
- trim( Filename ) + "." + trim( Ext ) )
- ELSE
- DELETE ALL FOR .NOT. Ext $ "PRG LBG FRG PRS FMT QBE UPD "
- ENDIF
- PACK
-
- * reuse again for .??O files
- RUN dir *.??o > &cString1.
- SELECT cObjfile
- APPEND FROM ( cString1 ) TYPE SDF
- DELETE ALL FOR left( Filename, 1 ) = " " .OR. right( Ext, 2 ) # "O "
- PACK
- ERASE ( cString1 )
-
- * assemble Runtime option
- cRunopt = iif( type( "cRun" ) = "C" .AND. "" # m->cRun ;
- .AND. left( m->cRun, 1 ) $ "Rr", " RUNTIME", "" )
-
- * now compile all the files that need it
- SELECT cSrcfile
- SCAN
- cString1 = trim( Filename ) + "." + trim( Ext )
- * Is there an object file of this name?
- IF Seek( Filename, "cObjfile" )
- cString2 = trim(cObjfile->Filename) + "." + trim(cObjfile->Ext)
- cString2 = dtos( fdate( m->cString2 ) ) + ftime( m->cString2 )
- * then check timestamps and skip it if already compiled
- IF dtos(fdate(m->cString1)) + ftime(m->cString1) < m->cString2
- LOOP
- ENDIF
- ENDIF
- * compile it otherwise, listing errors if enabled
- cString2 = m->cString1 + m->cRunopt
- * SET ALTERNATE ON
- * ? "Compiling " + m->cString2
- COMPILE &cString2.
- * ?
- * SET ALTERNATE OFF
- * and rename object files that should not be .DBOs
- IF Ext $ "FMT FRG LBG QBE "
- cString2 = stuff( m->cString1, len( m->cString1 ), 1, "O" )
- IF file( m->cString2 )
- ERASE ( m->cString2 )
- ENDIF
- cString1 = trim( Filename ) + ".DBO"
- RENAME ( m->cString1 ) TO ( m->cString2 )
- ENDIF
- ENDSCAN
-
- * Clean up
- USE
- ERASE ( m->cSrcfile + ".DBF" )
- SELECT cObjfile
- USE
- ERASE ( m->cObjfile + ".DBF" )
- ERASE ( m->cObjfile + ".MDX" )
- SET SAFETY &cSafety.
- SET DIRECTORY TO &cDir.
- SET ALTERNATE &cAlt.
- IF "" # m->cAlias
- SELECT ( m->cAlias )
- ENDIF
- SET CONSOLE &cCons.
-
- RETURN .T.
- *-- Eof() Recompile
-
- PROCEDURE Makedbf
- *----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302).
- *-- Date........: 04/26/1992
- *-- Notes.......: Makes an empty dBASE .dbf file
- *-- Written for.: dBASE IV, 1.1, 1.5
- *-- Rev. History: 04/26/1992 -- Original
- *-- Calls.......: Tempname() function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: DO MakeDbf WITH <cFilename>, <cStrufile>, <cArray>
- *-- Example.....: DO MakeDbf WITH Customers, cCustfields
- *-- Parameters..: cFilename - filename ( without extension ) of the
- *-- .dbf to be created.
- *-- cStrufile - name ( without extension ) of a STRUCTURE
- *-- EXTENDED .dbf
- *-- cArray - name of the array holding field
- *-- information for the .dbf. The array must
- *-- be dimensioned [ F, 5 ] where F is the
- *-- number of fields. Each row must hold
- *-- data for one field:
- *-- [ F, 1 ] field name, character
- *-- [ F, 2 ] field type, character from set "CDFLMN"
- *-- [ F, 3 ] field length, numeric. If field type is
- *-- D, L, or M, will be ignored
- *-- [ F, 4 ] field decimals, numeric. optional if 0.
- *-- [ F, 5 ] field is mdx tag, char $ "YN", optional
- *-- if N
- *----------------------------------------------------------------------
-
- parameters cFname, cSname, aAname
- private nX,cF1,cF2,cF3,cF4,cF5,cStrufile,cFtype
-
- cF1 = m->aAname + "[nX,1]"
- cF2 = m->aAname + "[nX,2]"
- cF3 = m->aAname + "[nX,3]"
- cF4 = m->aAname + "[nX,4]"
- cF5 = m->aAname + "[nX,5]"
- select select()
- use ( m->cSname ) ALIAS cSname
- zap
- nX = 1
- do while type( m->cF1 ) # "U"
- cFtype = &cF2.
- append blank
- replace Field_name with m->&cF1., Field_type with m->cFtype
- do case
- case m->cFtype = "D"
- replace Field_len with 8
- case m->cFtype = "M"
- replace Field_len with 10
- case m->cFtype = "L"
- replace Field_len with 1
- otherwise
- replace Field_len with m->&cF3.
- endcase
- if type( m->cF4 ) = "N" .and. m->cFtype $ "FN"
- replace Field_dec with m->&cF4.
- else
- replace Field_dec with 0
- endif
- if type(m->cF5) # "U" .and. m->cFtype $ "CDFN" .and. m->&cF5.= "Y"
- replace Field_idx with "Y"
- else
- replace Field_idx with "N"
- endif
- nX = m->nX + 1
- enddo
- use
- create ( m->cFname ) FROM ( m->cSname )
-
- RETURN
- *-- EoP: Makedbf
-
- PROCEDURE MakeDBF2
- *----------------------------------------------------------------------
- *-- Programmer..: Bowen Moursund (CIS: 72662,436)
- *-- Date........: 02/22/1993
- *-- Notes.......: Creates an empty DBF file of the structure specified
- *-- in the array aMakeDBF[], which must be declared and
- *-- initialized with the proper values before calling
- *-- this procedure. The array must be declared as
- *-- aMakeDBF[n,5], where n is the number of fields in the
- *-- DBF to be created. The columns of the array
- *-- correspond to the fields of a structure extended file
- *-- and must be initialized to the appropriate values,
- *-- before calling this procedure, 1 row for each field.
- *-- Structure of a structure extended file:
- *-- Field Type Len Dec
- *-- -----------------------
- *-- FIELD_NAME C 10 0
- *-- FIELD_TYPE C 1 0
- *-- FIELD_LEN N 3 0
- *-- FIELD_DEC N 3 0
- *-- FIELD_IDX C 1 0
- *--
- *-- aMakeDBF[n,1] = Field name: 10 or less characters
- *-- aMakeDBF[n,2] = Field type: 1 character
- *-- "C" = character
- *-- "N" = numeric
- *-- "F" = float
- *-- "D" = date
- *-- "L" = logical
- *-- "M" = memo
- *-- aMakeDBF[n,3] = Field length: numeric
- *-- "C" = 1 - 254
- *-- "N","F" = use dBASE guidelines
- *-- "D" = 8
- *-- "L" = 1
- *-- "M" = 10
- *-- aMakeDBF[n,4] = Decimal places: numeric
- *-- 0 for non numeric fields
- *-- aMakeDBF[n,5] = MDX flag: 1 char, "Y" or "N"
- *--
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 05/27/1992 -- Original Release
- *-- 02/22/1993 -- Minor changes to PRIVATE calls.
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: do MakeDBF with <cDBFpath>,<cStruPath>
- *-- Example.....: cStruPath = MakeStru2(.f.)
- *-- declare aMakeDBF[1,5]
- *-- aMakeDBF[1,1] = "FIELD1"
- *-- aMakeDBF[1,2] = "C"
- *-- aMakeDBF[1,3] = 20
- *-- aMakeDBF[1,4] = 0
- *-- aMakeDBF[1,5] = "N"
- *-- do MakeDBF2 with "foo", cStruPath
- *-- erase (cStruPath+".dbf")
- *-- release aMakeDBF
- *-- Returns.....: none
- *-- Parameters..: cDBFpath = the [path]filename of DBF to be created.
- *-- cStruPath = the [path]filename of an empty structure
- *-- extended file.
- *----------------------------------------------------------------------
-
- parameters cDBFpath,cStruPath
- if pcount() = 2 && we need 2 parms
- private cAlias
- if type("aMakeDBF[1,1]") = "C" && check array validity
- cAlias = alias()
- select select()
- use (m->cStruPath)
- append from array aMakeDBF
- use
- create (m->cDBFpath) from (m->cStruPath)
- use
- if "" # m->cAlias
- select (m->cAlias)
- endif
- endif
- endif
-
- RETURN
- *-- EoP: MakeDBF2
-
- FUNCTION Makestru
- *----------------------------------------------------------------------
- *-- Programmer..: Martin Leon (Hman), formerly sysop of A-T BBS
- *-- Revised by Jay Parsons, (CIS: 72662,1302).
- *-- Date........: 04/24/1992
- *-- Notes.......: Makes an empty dBASE STRUCTURE EXTENDED file and
- *-- returns its root name
- *-- Written for.: dBASE IV v1.5
- *-- Rev. History: 06/12/91 - original function.
- *-- 04/07/92 - Now takes no parameter, returns filename
- *-- 04/10/92 - Preserves catalog status and name
- *-- 04/24/92 - Use of Tempname() added
- *-- 05/28/92 - set("safety") check/minor mods, B.Moursund
- *-- Calls.......: Tempname() Function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: Makestru()
- *-- Example.....: Tempfile = Makestru()
- *-- Returns.....: Name of file created
- *-- Parameters..: None
- *----------------------------------------------------------------------
-
- private all
- lTitleOn = ( set("TITLE") = "ON" )
- lSafeOn = ( set("SAFETY") = "ON" )
- lCatOff = ( set("CATALOG") = "OFF" )
- cAlias = alias()
- cTmpCat = TempName("cat") + ".CAT"
- set title off
- set safety off
- cCatalog = catalog()
- set catalog to (cTmpCat)
- set catalog to &cCatalog.
- cStruName = TempName("dbf")
- select select()
- use (m->cTmpCat) nosave
- copy to (m->cStruName) structure extended
- use (m->cStruName) exclusive
- zap
- use
- if lTitleOn
- set title on
- endif
- if lSafeOn
- set safety on
- endif
- if lCatOff
- set catalog off
- endif
- if "" # m->cAlias
- select (m->cAlias)
- endif
-
- RETURN cStruname
- *-- Eof: Makestru()
-
- FUNCTION MakeStru2
- *----------------------------------------------------------------------
- *-- Programmer..: Bowen Moursund (CIS: 72662,436)
- *-- Date........: 05/27/1992
- *-- Notes.......: Create an empty STRUCTURE EXTENDED file, using DBASE
- *-- print redirection. If specified, the file will be
- *-- created in the subdirectory pointed to by the DOS
- *-- environment variable DBTMP, if it is set, otherwise
- *-- in the current subdirectory.
- *--
- *-- Structure of a STRUCTURE EXTENDED file:
- *-- Field Type Len Dec
- *-- -----------------------
- *-- FIELD_NAME C 10 0
- *-- FIELD_TYPE C 1 0
- *-- FIELD_LEN N 3 0
- *-- FIELD_DEC N 3 0
- *-- FIELD_IDX C 1 0
- *--
- *-- Written for.: dBASE IV v1.1
- *-- Rev. History: 05/27/1992 -- Original
- *-- Calls.......: TEMPNAME() Function in FILES.PRG
- *-- Called by...: Any, except when printing
- *-- Usage.......: MakeStru(<lDBTMP>)
- *-- Example.....: cStruPath = MakeStru2(.T.)
- *-- Returns.....: The name, no extension, of the file created.
- *-- Parameters..: lDBTMP = create file in DBTMP subdirectory, or not.
- *-- Side Effects: WARNING: Do not call when printing.
- *----------------------------------------------------------------------
-
- parameter lDBTMP
- private all
- cDBTMP = "" && TempName() will assign this, if lDBTMP
- if lDBTMP
- cFname = TempName( "dbf", .t. )
- else
- cFname = TempName( "dbf", .f. )
- endif
- cPath = iif( "" # m->cDBTMP, m->cDBTMP, ;
- set("DIRECTORY") ) + "\" + m->cFname + ".DBF"
- dDate = date()
- set printer to file (m->cPath)
- set printer on
- * Thanks to JPARSONS for suggestion to document the header structure
- ??? "{3}" && various bit flags
- ??? chr(year(dDate)-1900) + chr(month(dDate)) + ;
- chr(day(dDate)) && date bytes in YYMMDD format
- ??? "{0}{0}{0}{0}" && no. of records
- ??? "{193}{0}" && no. of bytes in header
- ??? "{19}{0}" && no. of bytes per record
- ??? "{0}{0}" && reserved
- ??? "{0}" && incomplete transaction flag
- ??? "{0}" && encryption flag
- ??? "{0}{0}{0}{0}{0}{0}{0}{0}{0}" + ;
- "{0}{0}{0}" && multi-user reserved
- ??? "{0}" && MDX flag
- ??? "{0}{0}{0}" && reserved
- * field descriptors
- * Field_Name
- ??? "{70}{73}{69}{76}{68}{95}{78}{65}{77}{69}{0}{67}{3}{0}{208}" + ;
- "{72}{10}{0}{0}{0}{1}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"
- * Field_Type
- ??? "{70}{73}{69}{76}{68}{95}{84}{89}{80}{69}{0}{67}{13}{0}{208}" +;
- "{72}{1}{0}{0}{0}{1}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"
- * Field_Len
- ??? "{70}{73}{69}{76}{68}{95}{76}{69}{78}{0}{0}{78}{14}{0}{208}" + ;
- "{72}{3}{0}{0}{0}{1}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"
- * Field_Dec
- ??? "{70}{73}{69}{76}{68}{95}{68}{69}{67}{0}{0}{78}{17}{0}{208}" + ;
- "{72}{3}{0}{0}{0}{1}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"
- * Field_Idx
- ??? "{70}{73}{69}{76}{68}{95}{73}{68}{88}{0}{0}{67}{20}{0}{208}" + ;
- "{72}{1}{0}{0}{0}{1}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"
- ??? "{13}{26}"
- set printer to
- set printer off
-
- RETURN cFname
- *-- Eof() MakeStru2
-
- FUNCTION TempName
- *----------------------------------------------------------------------
- *-- Programmer..: Martin Leon (HMAN) Former Sysop, ATBBS
- *-- Date........: 02/22/1993
- *-- Notes.......: Obtain a name for temporary file of a given extension
- *-- that does not conflict with existing files.
- *-- Written for.: dBASE IV, v1.5
- *-- Rev. History: Originally part of Makestru(), 6-12-1991
- *-- 04/26/92, made a separate function - Jay Parsons
- *-- 05/27/92, added lDBTMP option - Bowen Moursund
- *-- 02/22/93, Minor update to PRIVATE command.
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: TempName( cExt , lDBTMP )
- *-- Example.....: Sortfile = TempName( "DBF" , .t. )
- *-- Returns.....: Name not already in use. Additionally, if the memvar
- *-- cDBTMP is declared before calling the function with
- *-- the lDBTMP option, it will be assigned the result
- *-- of getenv("DBTMP").
- *-- Parameters..: cExt = Extension of temporary ( without the "." )
- *-- lDBTMP = Optional. If .t., function returns unique
- *-- file name in the DBTMP subdirectory.
- *-- Side Effects: The function will return a unique filename for the
- *-- DEFAULT subdirectory if the lDBTMP option is used and
- *-- the DOS environment variable DBTMP does not point to
- *-- a valid subdirectory.
- *----------------------------------------------------------------------
-
- parameters cExt, lDBTMP
- private cDefDir
- cDefDir = set("DIRECTORY")
- if lDBTMP
- cDBTMP = getenv("DBTMP")
- if "" # m->cDBTMP
- set directory to &cDBTMP.
- endif
- endif
- do while .t.
- Fname = "TMP" + ltrim( str( rand() * 100000, 5 ) )
- if .not. file(m->Fname + "." + m->cExt) .and. ;
- ( upper(m->cExt) # "DBF" .or. .not. ( file(m->Fname + ".MDX") ;
- .or. file (m->Fname + ".DBT") ) )
- exit
- endif
- enddo
- set directory to &cDefDir.
-
- RETURN Fname
- *-- Eof() TempName
-
- PROCEDURE FileMove
- *----------------------------------------------------------------------
- *-- Programmer..: David Frankenbach (FRNKNBCH)
- *-- DF Software Development, Inc.
- *-- PO Box 87
- *-- Forest, VA, 24551
- *-- (804) 237-2342
- *-- Date........: 02/11/1992
- *-- Notes.......: This procedure gives the record movement allowed with
- *-- EDIT when you use a simple @SAY/GET..READ. It allows
- *-- you to pre/post process each record during editing,
- *-- something you can't do with EDIT. This works best
- *-- with a single file, although it would work with a
- *-- parent->child relation. You should: SELECT child and
- *-- SET SKIP to child. This will allow the user to change
- *-- the parent record pointer though! If you want to
- *-- limit the child record movement to a single parent
- *-- record, you can use a conditional index, or add logic
- *-- to the routine to limit the record pointer movement.
- *-- For these cases I have a seperate FileMove procedure,
- *-- but they are not generic enough for publication.
- *--
- *-- These keys are trapped:
- *-- UpArw, Shift-Tab, LeftArw, Ctrl-LeftArw, PgUp =
- *-- backward one record
- *-- DnArw, Tab, RightArw, Ctrl-RightArw, PgDn, Enter,
- *-- Ctrl-End = forward one record
- *-- Ctrl-PgUp = top of database or active index
- *-- Ctrl-PgDn = bottom of database or active index
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 06/17/1991 - original routine.
- *-- 02/07/1992 -- Ken Mayer, brought into one PROCEDURE,
- *-- rather than a function and a procedure ...
- *-- 02/11/1992 -- Author, additional documentation
- *-- Released into Public Domain
- *-- Calls.......: None
- *-- Called by...: None
- *-- Usage.......: do FileMove with <nKey>
- *-- where: <nKey> is the return value of readkey()
- *-- Parameters..: nKey = last keystroke from a READKEY() call ...
- *-- Returns.....: None
- *-- Side Effects: Moves record pointer in current file if lMove = .t.
- *-- Example.....:
- *-- lMove = .t. && if you want the user to be able to
- *-- && move the record pointer in my
- *-- && applications if the user is adding a
- *-- && new record I usually lMove = .f., for
- *-- && editing I allow them to move through
- *-- && the records.
- *-- lOk = .t.
- *-- do while ( lOk )
- *-- do Mem_Load && load memvars from record
- *-- @say/gets && display/get the memvars
- *-- read
- *-- i = readkey() && grab last key ...
- *-- lOk = ( i <> 27 ) && if Esc was pressed lOK is false
- *-- if ( lOk )
- *-- if ( i > 256 ) && if record is changed
- *-- do Mem_Unload && replace dbf fields from memvars
- *-- endif && ( i > 256 )
- *-- if ( lMove ) && if ok to move record pointer
- *-- do FileMove with i && <----- Move it
- *-- else
- *-- lOk = .f. && terminate loop if .not. lMove
- *-- endif && ( lMove )
- *-- endif && (lOK)
- *-- enddo && while (lOK)
- *----------------------------------------------------------------------
- parameter nKey
- private n
-
- m->n = m->nKey
- if ( m->n > 255 ) && if value is > 256, record has changed, but
- m->n = m->n - 256 && we want values < 256 to figure out which
- endif && direction to move from the readkey() table
-
- do case
-
- *-- keys to move backward through database 1 record at a time ...
- *-- LeftArw, Ctrl-LeftArw, UpArw, Shift-Tab, PgUp
- case ( m->n = 0 ) .or. ( m->n = 2 ) .or. ;
- ( m->n = 4 ) .or. ( m->n = 6 )
- if ( .not. bof() ) && if not at beginning of file
- skip -1 && move backward one record
- endif
-
- *-- keys to move forward through database 1 record at a time ...
- *-- RightArw, Ctrl-RightArw, DownArw, Tab, PgDn, Ctrl-End, Enter
- case ( m->n = 1 ) .or. ( m->n = 3 ) .or. ;
- ( m->n = 5 ) .or. ( m->n = 7 ) .or. ;
- ( m->n = 14) .or. ( m->n = 15)
- if ( .not. eof() ) && if not end of file
- skip 1 && move forward one record
- endif
- if ( eof() ) && if we're now at the EOF,
- goto bottom && go back to last record...
- endif
-
- *-- go to toP of database, Ctrl-PgUp
- case ( m->n = 34 )
- goto top
-
- *-- go to BOTtoM of database, Ctrl-PgDn
- case ( m->n = 35 )
- goto bottom
-
- endcase
-
- RETURN
- *-- EoP: FileMove
-
- FUNCTION Used
- *----------------------------------------------------------------------
- *-- Programmer..: Ken Mayer (CIS: 71333,1030)
- *-- Date........: 02/28/1992
- *-- Notes.......: Created because the picklist routine by Malcolm Rubel
- *-- from DBA Magazine (11/91) calls a function that
- *-- checks to see if a DBF file is open ...
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 05/15/1992 -- Original
- *-- 02/08/1993 -- Discovered (thanks to Jay, and then
- *-- Malcolm) a much simpler way to do this ...
- *-- Called by...: Any
- *-- Calls.......: None
- *-- Usage.......: Used("<cFile>")
- *-- Example.....: if used("Library")
- *-- select library
- *-- else
- *-- select select()
- *-- use library
- *-- endif
- *-- Returns.....: Logical (.t. if file is in use, .f. if not)
- *-- Parameters..: cFile = file to check for
- *----------------------------------------------------------------------
-
- parameters cFile
-
- RETURN (select(cFile) # 0)
- *-- EoF: Used()
-
- FUNCTION MDXbyte
- *----------------------------------------------------------------------
- *-- Programmer..: Bowen Moursund (CIS: 72662,436)
- *-- Date........: 05/21/1992
- *-- Notes.......: Sets the MDX byte in a DBF header ON or OFF.
- *-- The DBF must not be open when the function is called.
- *-- Written for.: dBASE IV v1.5
- *-- Rev. History: 05/21/1992 -- Original
- *-- Calls.......: dBASE low level file functions
- *-- Called by...: Any
- *-- Usage.......: MDXbyte(<cDBFpath>,<cOnOff>)
- *-- Example.....: lByteSet = MDXbyte("mydbf.dbf","OFF")
- *-- Returns.....: .T. if successful
- *-- Parameters..: cDBFpath = the [path]filename.ext of the DBF
- *-- cOnOff = "ON" or "OFF"
- *----------------------------------------------------------------------
-
- parameters cDBFpath,cOnOff
- private all
-
- cOnOff = upper(m->cOnOff)
- * check the validity of the parameters
- lSuccess = ( pcount() = 2 .AND. m->cOnOff $ "ON|OFF" .AND. ;
- file(m->cDBFpath) )
- if lSuccess
- nHandle = fopen(m->cDBFpath,"RW")
- if m->nHandle > 0
- if fseek(m->nHandle, 28) = 28
- lSuccess = ( fwrite(m->nHandle, iif(m->cOnOff="OFF",;
- chr(0),chr(1))) = 1 )
- else
- lSuccess = .F.
- endif
- lClosed = fclose(m->nHandle)
- else
- lSuccess = .F.
- endif
- endif
-
- RETURN m->lSuccess
- *-- Eof() MDXbyte
-
- FUNCTION aDir
- *----------------------------------------------------------------------
- *-- Programmer..: Bowen Moursund (CIS: 72662,436)
- *-- Date........: 02/22/1993
- *-- Notes.......: aDir() creates a public array gaDir[ n, 5 ]
- *-- containing directory information. gaDir[ n, 5 ] is
- *-- limited to 234 rows (files) or less, depending on
- *-- memory available.
- *--
- *-- Structure of 2D array gaDir[ n, 5 ]:
- *--
- *-- Col Contents Type Width
- *-- ------------------------------------------
- *-- 1 File Name Character 12
- *-- 2 Date (mm/dd/yy) Date 8
- *-- 3 Time (hh:mm:ss) Character 8
- *-- 4 Size (bytes) Numeric 10
- *-- 5 Attributes Character 6
- *--
- *-- aDir() makes use of SEARCH.BIN, and credit is due its
- *-- author (Roland Boucherau, Borland Technical Support).
- *-- See SEARCH.ASM or SEARCH.TXT source for details.
- *-- *****************************
- *-- **** REQUIRES SEARCH.BIN ****
- *-- *****************************
- *-- Written for.: dBASE IV, v1.5
- *-- Rev. History: 07/24/1992 -- Original Release
- *-- 02/22/1993 -- Minor Update to PRIVATE call.
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: adir( <cFMask>, <cBINpath>, <cAttr> )
- *-- Examples....: nFiles = adir( "d:\app\fu*.db?", ;
- *-- "d:\dbase4\library\", "" )
- *-- nFiles = adir( cPathSkel )
- *-- nFiles = adir( "c:\*.*", "", "RHSD" )
- *-- Returns.....: Number of matching files found: rows in gaDir[]
- *-- Parameters..: cPathSkel = directory path and file skeleton that you
- *-- want, like DOS DIR command. Wildcards OK.
- *-- cBINpath = Optional path to Search.Bin. If omitted,
- *-- Search.Bin must be in current
- *-- subdirectory. Include the trailing "\".
- *-- cAttr = Optional file attribute mask string.
- *--
- *-- Mask Codes
- *-- ------------
- *-- R - Read Only
- *-- H - Hidden
- *-- S - System
- *-- D - Directory
- *-- V - Volume
- *-- A - Archive
- *--
- *-- If cAttr is omitted, null, or blank, gaDir[] will
- *-- contain only 'ordinary' files, i.e. files without
- *-- HSDV attributes. If V is specified in the mask,
- *-- ONLY volume labels are matched. Any other attribute
- *-- or combination of attributes results in those files
- *-- AND ordinary files being matched.
- *----------------------------------------------------------------------
-
- parameters cPathSkel, cBINpath, cAttr
- private cModule,cAttr,cFSkel,cFName,cFDate,cFTime,cFSize,cFAttr,;
- nMaxRows,m->nFCount,nResult,n
-
- cModule = iif( pcount() >= 2, ;
- m->cBINpath + "search.bin", "search.bin" )
- store upper( iif( pcount() >= 3, ;
- left( m->cAttr + " ", 6 ), " " ) ) ;
- to cAttr, cFAttr
- cFSkel = left(m->cPathSkel + space(12), max(len(m->cPathSkel),12))
- cFName = m->cFSkel
- * ( memory() * 3.4 ) is just a GUESS on max rows before
- * 'Insufficient Memory' occurs
- nMaxRows = min( memory() * 3.4, 234 ) && 234 is absolute maximum
- nFCount = 0
- load ( m->cModule )
- nResult = call( "Search", 1, m->cFName, m->cAttr )
- if m->nResult = 0
- do while m->nResult = 0 .and. m->nFCount <= m->nMaxRows
- nFCount = m->nFCount + 1
- nResult = call( "Search" , 2, m->cFName )
- enddo
- nFCount = min( m->nMaxRows, m->nFCount )
- release gaDir
- public array gaDir[ m->nFCount, 5 ]
- cFName = m->cFSkel
- cFDate = " / / "
- cFTime = " : : "
- nFSize = 0
- n = 1
- nResult = ;
- call( "Search", 1, m->cFName, m->cFAttr, m->cFDate, ;
- m->cFTime, m->nFSize )
- do while m->nResult = 0 .AND. m->n <= m->nFCount
- store m->cFName to gaDir[ m->n, 1 ]
- store ctod( m->cFDate ) to gaDir[ m->n, 2 ]
- store m->cFTime to gaDir[ m->n, 3 ]
- store m->nFSize to gaDir[ m->n, 4 ]
- store m->cFAttr to gaDir[ m->n, 5 ]
- nResult = call( "Search", 2, m->cFName, m->cFAttr, ;
- m->cFDate, m->cFTime, m->nFSize )
- n = m->n + 1
- enddo
- else
- release gaDir
- endif
- release module Search
-
- RETURN m->nFCount
- *-- EoF: aDir()
-
- FUNCTION DbfDir
- *----------------------------------------------------------------------
- *-- Programmer..: Bowen Moursund (CIS: 72662,436)
- *-- Date........: 07/03/1992
- *-- Notes.......: DbfDir() creates or OVERWRITES DbfDir.Dbf, and
- *-- populates it with directory information. The function
- *-- uses the DOS 5.0 DIR command and requires DOS 5.0.
- *--
- *-- Structure of DBFDIR.DBF
- *-- -----------------------
- *-- Field Type Len Dec
- *-- F_NAME C 12 0
- *-- F_DATE D 8 0
- *-- F_TIME C 8 0
- *-- F_SIZE N 10 0
- *-- *************************************************
- *-- * DO NOT CALL THIS ROUTINE WHILE PRINTING *
- *-- * (the function uses Print Redirection ...) *
- *-- *************************************************
- *-- Written for.: dBASE IV v1.5, DOS 5.0
- *-- Rev. History: 07/03/1992 -- Original
- *-- Calls.......: TempName() Function in FILES.PRG
- *-- Called by...: None
- *-- Usage.......: DbfDir( "<cPathSkel>", <lHidSys> )
- *-- Examples....: nFiles = DbfDir( "*.dbf" )
- *-- nFiles = DbfDir( "*.dbf", .t. )
- *-- Returns.....: Number of matching files found: reccount() of DbfDir
- *-- Parameters..: cPathSkel = directory path and file skeleton that you
- *-- want, like DOS DIR command. Wildcards OK.
- *-- lHidSys = Optional. If .t., hidden & system files
- *-- are included.
- *----------------------------------------------------------------------
-
- parameters cPathSkel, lHidSys
- private all
-
- cDBTMP = ""
- cTmpFile = tempname( "txt", .t. ) + ".txt"
- cTmpFile = iif(""=cDBTMP, m->cTmpFile, cDBTMP + "\" + m->cTmpFile)
- cDirParms = iif( m->lHidSys, "/B/A-D/ON", "/B/A-D-H-S/ON" )
- run dir &cPathSkel. &cDirParms. > &cTmpFile.
- nFiles = 0
- if fsize( m->cTmpFile ) > 0
- lSafeOn = ( set( "safety" ) = "ON" )
- set safety off
- set printer to file DbfDir.dbf && create DbfDir.dbf
- set printer on
- * first byte of header - various bit flags
- ??? "{3}"
- * next 3 bytes - file date in binary YYMMDD
- ??? chr(year(date())-1900)+chr(month(date()))+chr(day(date()))
- * the rest of the header, field descriptors, and records if any
- ??? "{0}{0}{0}{0}{161}{0}{39}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"+;
- "{0}{0}{0}{0}{0}{0}{0}{0}{0}{1}{1}{70}{95}{78}{65}{77}"+;
- "{69}{0}{0}{0}{0}{0}{67}{0}{0}{0}{0}{12}{0}{0}{0}{0}{0}"+;
- "{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{70}{95}{68}{65}{84}{69}"+;
- "{0}{0}{0}{0}{0}{68}{0}{0}{0}{0}"
- ??? "{8}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{70}{95}"+;
- "{84}{73}{77}{69}{0}{0}{0}{0}{0}{67}{0}{0}{0}{0}{8}{0}{0}"+;
- "{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{70}{95}{83}{73}"+;
- "{90}{69}{0}{0}{0}{0}{0}{78}{0}{0}{0}{0}{10}{0}{0}{0}{0}"+;
- "{0}{0}{0}{0}{0}{0}{0}{0}"
- ??? "{0}{0}{0}{13}{26}"
- set printer to
- set printer off
- cAlias = alias()
- select select()
- use DbfDir
- append from ( m->cTmpFile ) sdf
- goto top
- cPath = parspath( m->cPathSkel )
- scan
- replace f_size with fsize( cPath + f_name ),;
- f_date with fdate( cPath + f_name ),;
- f_time with ftime( cPath + f_name )
- endscan
- nFiles = reccount()
- use
- if lSafeOn
- set safety on
- endif
- if "" # m->cAlias
- select ( m->cAlias )
- endif
- endif
- erase ( m->cTmpFile )
-
- RETURN m->nFiles
- *-- EoF: DBFDir()
-
- FUNCTION ParsPath
- *----------------------------------------------------------------------
- *-- Programmer..: Bowen Moursund (CIS: 72662,436)
- *-- Date........: 07/16/1992
- *-- Notes.......: ParsPath() extracts and returns the path from a
- *-- full path file specification.
- *-- Written for.: dBASE IV v1.1
- *-- Rev. History: 07/16/1992 -- Original
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: ParsePath( "<cFullPath>" )
- *-- Example.....: set fullpath on
- *-- cDBF = dbf()
- *-- cPath = ParsPath( cDBF )
- *-- Returns.....: The path only, including the trailing backslash,
- *-- of the full path file specification
- *-- Parameters..: cFullPath = a full path file spec,
- *-- e.g. "c:\dbase\dbase.exe"
- *----------------------------------------------------------------------
-
- parameter cFullPath
- private all
-
- cPath = ""
- if "\" $ m->cFullPath
- nPos = 1
- do while left( right ( m->cFullPath, m->nPos ), 1 ) # "\"
- nPos = m->nPos + 1
- enddo
- cPath = substr(m->cFullPath, 1, len(m->cFullPath) - m->nPos + 1)
- endif
-
- RETURN cPath
- *-- EoF: ParsPath()
-
- PROCEDURE TagPop
- *----------------------------------------------------------------------
- *-- Programmer..: Ken Mayer (CIS: 71333,1030)
- *-- Date........: 06/30/1993
- *-- Notes.......: Used to bring up a list of MDX tags on screen for the
- *-- user, so they can change the current tag ... This is
- *-- based on an article by Susan Perschke and Mike
- *-- Liczbanski in "Data Based Advisor", December, 1991,
- *-- and another by Malcom C. Rubel, Data Based Advisor,
- *-- September, 1992.
- *-- The idea is to bring up a picklist of all MDX tags
- *-- for the current database file, showing the tag name,
- *-- and expression, as well as whether or not it's
- *-- unique, has a FOR clause, and whether it's ascending
- *-- or descending ...
- *-- However, as an additional bonus, if the user selects
- *-- one of the MDX tags, the current tag is changed to
- *-- the one the user selects. The tag with a "*" by it is
- *-- the current tag.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 09/08/1992 -- Version 1
- *-- 09/21/1992 -- Version 1.1 -- added more docs and
- *-- removed reference to parameters of
- *-- which there are none ... (changed
- *-- my mind)
- *-- 06/30/1993 -- Version 2 -- 3-D look and feel, added
- *-- color parameter back in, size of dialog
- *-- box changes based on # of .MDX tags in
- *-- file, and optional parameter ...
- *-- Calls.......: SHADOW Procedure in PROC.PRG
- *-- CENTER Procedure in PROC.PRG
- *-- BORD3D Procedure in PROC.PRG
- *-- COLORBRK() Function in PROC.PRG
- *-- RECOLOR Procedure in PROC.PRG
- *-- Called by...: Any
- *-- Usage.......: DO TagPop [with <cColor>[,<cCurTag>]]
- *-- Example.....: ON KEY LABEL F8 DO TagPop with "","TITLE"
- *-- Returns.....: None (well, ok -- it resets MDX tag if you select 1)
- *-- Parameters..: cColor = optional color parameter ...
- *-- cCurTag = optional -- "current" tag for those
- *-- routines where, perhaps, the tag is not
- *-- "currently" active, but programmer may need
- *-- one as the "current" tag.
- *----------------------------------------------------------------------
-
- parameters cColor,cCurTag
- private nBar, cPrompt, cBorder, cTag, nTag, nTagTotal, cFor, ;
- cUnique, cDir, cKey, cTemp1, cTemp2, cOldCol
-
- *-- if no colors passed, use Borland "steel grey" look
- if pCount() = 0
- cColor = "n/w,w+/n,n/w"
- else
- if isblank(m->cColor)
- cColor = "n/w,w+/n,n/w"
- endif
- endif
-
- *-- deal with cCurTag
- if pCount() < 2
- cCurTag = trim(order())
- else
- cCurTag = trim(upper(m->cCurTag)) && just to be sure
- endif
-
- *-- Disable left/right arrow keys to prevent an accidental exit
- on key label leftarrow ?? chr(7)
- on key label rightarrow ?? chr(7)
-
- *-- Save current screen
- save screen to sTag
- cBorder = set("BORDER")
- activate screen
-
- *-- determine number of tags in current .MDX
- nTags = tagcount()
-
- *-- define the screen/window
- nTop = 5
- nLeft = 2
- nBottom = m->nTop + iif(m->nTags > 4, m->nTags, 4) + 12
- nBottom = iif(m->nBottom > 22, 22, m->nBottom)
- nRight = 77
- define window wTagPop from m->nTop,m->nLeft to m->nBottom,m->nRight;
- NONE color &cColor.
- activate screen
- do shadow with m->nTop,m->nLeft,m->nBottom,m->nRight
- activate window wTagPop
- do bord3d with 0,0,m->nBottom-m->nTop,m->nRight-m->nLeft,;
- colorbrk(m->cColor,1),1
-
- *-- check to see if there are any tags ... or an active database ...
- if isblank(alias()) .or. isblank(tag(1))
-
- *-- if not, display appropriate error message
- if isblank(alias())
- do center with 2,75,"","** No active Database ... **"
- else
- do center with 2,75,"",;
- "** No active .MDX file for this .DBF **"
- endif
- x=inkey(0) && wait for user to press a key ...
-
- else && we DO have an active database AND active MDX file
-
- *-- headings
- cTextCol = colorbrk(m->cColor,1)
- do center with 1,75,m->cTextCol," Select new MDX Tag "
- @3, 4 say "Name" color &cTextCol.
- @3,13 say "For" color &cTextCol.
- @3,17 say "Unq" color &cTextCol.
- @3,21 say "Seq" color &cTextCol.
- @3,25 say "Expression" color &cTextCol.
- do bord3d with 2,3,4,72,colorbrk(m->cColor,1),3
-
- *-- popup will display here
-
- *-- footings (as it were)
- nBotLine = nBottom-nTop
- nLine = nBotLine-6
- do bord3d with m->nLine,3,m->nLine+4,72,colorbrk(m->cColor,1),4
- @nLine+1,5 say chr(251)+;
- " in 'For' column means there is a 'For' clause";
- color &cTextCol.
- @nLine+2,5 say chr(251)+;
- " in 'Unq' column means the tag is set to 'Unique'";
- color &cTextCol.
- @nLine+3,5 say chr(24)+;
- " in 'Seq' means tag is 'Ascending', "+;
- chr(25)+" means tag is 'Descending'" color &cTextCol.
-
- *-- define the popup
- set border to none && no border for popup
- nPopTop = 4
- * account for "border" even if there is none
- nPopBottom = iif(m->nTags > 7, 9, m->nPopTop + m->nTags) + 1
- define popup pTag from m->nPopTop,3 to m->nPopBottom,72 message ;
- " Press ENTER to select new index order ... ESC to exit ..."
- nBar = 1 && first bar
- *-- place a * if no tag is currently active
- cPrompt = iif((TagNo()=0) .and. isblank(m->cCurTag),"*"," ")+;
- " No Index" && bar 1 will always be this
- cPrompt = m->cPrompt + space(11)+"(Natural Order)"
- nTag = 0
-
- *-- loop to get the rest of 'em ...
- nTagTotal = tagcount() && get total number of tags
- do while m->nTag <= m->nTagTotal && loop until no more tags
- define bar nBar of pTag prompt (m->cPrompt)
- nTag = m->nTag + 1
- cDefault = iif( (trim(tag(m->nTag)) = m->cCurTag) .and.;
- .not. isblank(m->cCurTag),;
- "*"," ") && if current tag ...
- *-- the fun part is getting the spacing "just right"
- *-- that's what all the IIF( ....,space(...)) stuff is about
- cTag = tag(m->nTag) + iif(len(tag(m->nTag)) < 9, ;
- space(9-len(tag(m->nTag))),"")
- cFor = iif(isblank(for(m->nTag))," ",chr(251))
- cUnique = iif(unique(m->nTag),chr(251)," ")
- cDir = iif(descending(m->nTag),chr(25),chr(24))
- && up/down arrows ...
- cKey = iif(len(key(m->nTag))>57,left(key(m->nTag),52)+;
- " ...",key(m->nTag))
- cKey = iif(len(m->cKey)<57,m->cKey + ;
- space(57-len(m->cKey)),m->cKey)
- *-- here's the actual definition of the bars ...
- cPrompt = m->cDefault + m->cTag + " " + m->cFor + " " + ;
- m->cUnique + " " + m->cDir + " " + m->cKey
- nBar = m->nBar + 1
- enddo
-
- *-- turn it off when an item has been selected or <Esc> pressed
- on selection popup pTag deactivate popup
-
- *-- do it
- cOldCol = set("ATTRIBUTE")
- cTemp1 = colorbrk(m->cColor,1)
- cTemp2 = colorbrk(m->cColor,2)
- set color of message to &cTemp1.
- set color of box to &cTemp1.
- set color of highlight to &cTemp2.
- activate popup pTag
-
- *-- Don't change index order if ESC pressed
- if bar() <> 0
- *-- Assign a null string to cPrompt if "No Index" selected
- cPrompt = iif(bar() = 1, "",tag(bar()-1))
- set order to (m->cPrompt)
- endif
-
- *-- cleanup
- do recolor with m->cOldCol
- release popup pTag
- set border to &cBorder.
-
- endif
- release window wTagPop
- restore screen from sTag
- release screen sTag
-
- *-- re-enable left/right arrow keys
- on key label leftarrow
- on key label rightarrow
-
- RETURN
- *-- EoP: TagPop
-
- FUNCTION AAppend
- *----------------------------------------------------------------------
- *-- Programmer..: Adam L. Menkes (Borland Technical Support)
- *-- Date........: 10/26/1993
- *-- Notes.......: Appends a text file into an array. This routine is
- *-- limited to text files of 1,170 lines, and 254 char-
- *-- acters per line. The text file must be an ASCII Txt
- *-- formatted file. Taken from Technotes, April, 1992.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/01/1992 -- Original
- *-- : 10/26/1993 Angus Scott-Fleming release "ALL LIKE"
- *-- Calls.......: TextLine() Function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: AAppend(<cFileName>,<aArrayName>)
- *-- Example.....: ?AAppend("CONFIG.DB","aConfig")
- *-- Returns.....: .T.
- *-- Parameters..: cFileName = Name of DOS Text file to read into array
- *-- aArrayName = Name of array to create. If it already
- *-- exists, this array will be destroyed and
- *-- overwritten.
- *----------------------------------------------------------------------
-
- parameters cFileName, aArrayName
- private aTArray, nLines, nX, nHandle
-
- *-- assign array name to a temp variable name ...
- aTArray = m->aArrayName
- *-- if it exists, get rid of it, and then re-define it
- *-- Tue 10-26-1993 original code release &aTArray. wasn't working
- release all like &aTArray.
- aTArray = m->aArrayName
- public &aTArray.
- nLines = TextLine(m->cFileName) && get number of lines
- declare &aTArray.[min(m->nLines,1170)]
-
- *-- get file handle
- nHandle = fopen(m->cFileName)
-
- *-- store the file into the array
- nX = 1
- do while m->nX <= m->nLines
- store fgets(m->nHandle,254) to &aTArray.[m->nX]
- nX = m->nX + 1
- enddo
-
- *-- close the file
- nHandle = fClose(m->nHandle)
-
- RETURN .T.
- *-- EoF: AAppend()
-
- FUNCTION FDel
- *----------------------------------------------------------------------
- *-- Programmer..: Adam L. Menkes (Borland Technical Support)
- *-- Date........: 04/01/1992
- *-- Notes.......: Deletes a given portion of a file. Taken from
- *-- TechNotes, April, 1992
- *-- Used to delete a portion of a file (text or binary)
- *-- from the beginning of the file, the end of file or
- *-- current pointer position. This routine accomplishes
- *-- its task by writing the data you want to keep to a
- *-- temp file, then overwriting the data you no longer
- *-- want with the temp file. If you are on a network,
- *-- make sure that you set TMP (or DBTMP) to either a
- *-- local drive, or one where you have full rights.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/01/1992 -- Original
- *-- Calls.......: TempFile() Function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: FDel(<nHandle>,<nBytes>,<nStart>)
- *-- Example.....: nOpen = fopen("TEXT.TXT","RW")
- *-- ?FDel(nOpen,1000,1)
- *-- Returns.....: Logical
- *-- Parameters..: nHandle = file handle number, as returned by FOPEN
- *-- nBytes = number of chars (bytes) to delete in file
- *-- nStart = starting position, where:
- *-- 0 is the beginning of the file
- *-- 1 is the current file pointer position
- *-- 2 is the end of the file
- *----------------------------------------------------------------------
-
- parameters nHandle, nBytes, nStart
- private nTemp,cTemp,nSave,nSeek,nRead,nWrite,lFlush,nClose
-
- *-- create a temporary file
- cTemp = tempfile("ADM")
- *-- save current position in file
- nSave = fseek(m->nHandle,0,1)
-
- do case
- case m->nStart = 0 && beginning of file
- nSeek = fseek(m->nHandle, m->nBytes, 0)
- nTemp = fcreate(m->cTemp)
- do while .not. feof(m->nHandle)
- nRead = fread(m->nHandle,254)
- nWrite = fwrite(m->nTemp,m->nRead)
- lFlush = fflush(m->nTemp)
- enddo
- nSeek = fseek(m->nTemp,0,0)
- nSeek = fseek(m->nHandle,0,0)
- do while .not. feof(m->nTemp)
- nRead = fread(m->nTemp,254)
- nWrite = fwrite(m->nHandle,m->nRead)
- lFlush = fflush(m->nHandle)
- enddo
- nWrite = fwrite(m->nHandle,chr(0),0)
- nClose = fclose(m->nTemp)
- nSeek = fseek(m->nHandle,m->nSave,0)
-
- case m->nStart = 1 && Current Location
- *-- skip these bytes
- nSeek = fseek(m->nHandle,m->nDelete,1)
- *-- write the rest to a temp file
- nTemp=fCreate(m->cTemp)
- do while .not. feof(m->nHandle)
- nRead = fread(m->nHandle,254)
- nWrite = fwrite(m->nTemp,m->nRead)
- lFlush = fflush(m->nTemp)
- enddo
-
- nSeek = fseek(m->nTemp,0,0)
- nSeek = fseek(m->nHandle,m->nSave,0)
- nWrite = fwrite(m->nHandle,chr(0),0)
-
- do while .not. feof(m->nTemp)
- nRead = fread(m->nTemp,254)
- nWrite = fwrite(m->nHandle,m->nRead)
- lFlush = fflush(m->nHandle)
- enddo
- nSeek = fseek(m->nHandle,m->nSave,0)
- nClose = fclose(m->nTemp)
-
- case m->nStart = 2 && End of File
- nSeek = fseek(m->nHandle,-1*abs(m->nDelete),2)
- nWrite = fwrite(m->nHandle,chr(0),0)
- endcase
- erase (m->cTemp)
-
- RETURN (ferror() = 0)
- *-- EoF: FDel()
-
- FUNCTION FGetLine
- *----------------------------------------------------------------------
- *-- Programmer..: Adam L. Menkes (Borland Technical Support)
- *-- Date........: 04/01/1992
- *-- Notes.......: Used to extract a line of text from a text file.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/01/1992 -- Original
- *-- Calls.......: TLine() Function in FILES.PRG
- *-- TLineNo() Function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: FGetLine(<cFileName>,<cLookup>,[<lCase>],[<lEntire>])
- *-- Example.....: ?FGetLine("config.db","command",.f.,.f.)
- *-- Returns.....: A character expression
- *-- Parameters..: cFileName = Name of file to extract text from
- *-- cLookup = Text to look for
- *-- lCase = Case sensitive? (Logical = .t. or .f.)
- *-- If empty, default is .F.
- *-- lEntire = Return entire line, or the rest of line
- *-- .t. = return the entire line
- *-- .f. = return everything following cLookup
- *-- If empty, default is .t.
- *----------------------------------------------------------------------
-
- parameters cFileName, cLookup, lCase, lEntire
- private nLine, cText
-
- *-- defaults
- lCase = iif(pcount() <= 2,.f.,m->lCase)
- lEntire = iif(pcount() <=3,.t.,m->lEntire)
- *-- get the line ...
- nLine = TLineNo(m->cFile,m->cLookup,m->lCase)
- cText = iif(m->nLine<=0,"",TLine(m->cFile,m->nLine,m->lCase))
- cResult = upper(m->cText)
-
- RETURN iif( m->lEntire, m->cText, ;
- substr(m->cText,at(upper(m->cLookup),m->cResult)+len(m->cLookup)) )
- *-- EoF: FGetLine()
-
- FUNCTION FIns
- *----------------------------------------------------------------------
- *-- Programmer..: Adam L. Menkes (Borland Technical Support)
- *-- Date........: 04/01/1992
- *-- Notes.......: Inserts specified number of NULLS into a low-level
- *-- file. Taken from Technotes, April, 1992. FIns() works
- *-- the way FDel() works, but in reverse. See comments
- *-- in FDel about temp directory ...
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/01/1992 -- Original
- *-- Calls.......: TempFile() Function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: FIns(<nHandle>,<nBytes>,<nStart>)
- *-- Example.....: nOpen = fopen("TEST.TXT","RW")
- *-- ?FIns(nOpen,10,1)
- *-- Returns.....: Logical
- *-- Parameters..: nHandle = File Handle from FOPEN() function
- *-- nBytes = Number of nulls to insert into file
- *-- nStart = Location in file to start at, where:
- *-- 0 = Beginning of file
- *-- 1 = Current file pointer
- *-- 2 = End of file
- *----------------------------------------------------------------------
-
- parameters nHandle, nBytes, nStart
- private nTemp, cTemp, nSave, nRead, nWrite, nSeek, lFlush, nX,nClose
-
- cTemp = TempFile("ADM") && create temp file
- nSave = fseek(m->nHandle,0,1) && save current position
-
- do case
- case m->nStart = 0 && beginning of file
- nTemp = fcreate(m->cTemp)
- nX = 1
- do while m->nX <= m->nBytes
- nWrite = fwrite(m->nTemp,chr(0),1)
- nX = m->nX + 1
- enddo
- nSeek = fseek(m->nHandle,0,0)
- do while .not. feof(m->nHandle)
- nRead = fread(m->nHandle,254)
- nWrite = fwrite(m->nTemp,m->nRead)
- lFlush = fflush(m->nTemp)
- enddo
- nSeek = fseek(m->nTemp,0,0)
- nSeek = fseek(m->nHandle,0,0)
- do while .not. feof(m->nTemp)
- nRead = fread(m->nTemp,254)
- nWrite = fwrite(m->nHandle,m->nRead)
- lFlush = fflush(m->nHandle)
- enddo
- nWrite = fwrite(m->nHandle,chr(0),0)
- nclose = fclose(m->ntemp)
- nSeek = fseek(m->nHandle,0,0)
-
- case m->nStart = 1 && current location
- *-- write the rest to a temp file
- nTemp = fcreate(m->cTemp)
- do while .not. feof(m->nHandle)
- nRead = fread(m->nHandle,254)
- nWrite = fwrite(m->nTemp,m->nRead)
- lFlush = fflush(m->nTemp)
- enddo
- nSeek = fseek(m->nHandle,m->nSave,0)
- nX = 1
- do while m->nX <= m->nBytes
- nWrite = fWrite(m->nHandle,chr(0),1)
- nX = m->nX + 1
- enddo
- nSeek = fseek(m->nTemp,0,0)
- do while .not. feof(m->nTemp)
- nRead = fread(m->nTemp,254)
- nWrite = fwrite(m->nHandle,m->nRead)
- lFlush = fflush(m->nHandle)
- enddo
- nSeek = fseek(m->nHandle,m->nSave,0)
- nClose = fclose(m->nTemp)
-
- case m->nStart = 2 && End of File
- nSeek = fseek(m->nHandle,0,2)
- nX = 1
- do while m->nX <= m->nBytes
- nWrite = fwrite(m->nHandle,chr(0),1)
- nX = m->nX + 1
- enddo
- endcase
- erase (m->cTemp)
-
- RETURN (ferror() = 0)
- *-- EoF: FIns()
-
- FUNCTION GetInfo
- *----------------------------------------------------------------------
- *-- Programmer..: Adam L. Menkes (Borland Technical Support)
- *-- Date........: 10/26/1993
- *-- Notes.......: Retrieves information from STATUS that you cannot get
- *-- with the dBASE IV function SET(). See 'parameters'
- *-- below for list of keywords.
- *-- CAUTION: If you have ALTERNATE set, you need to reset
- *-- it after the function executes. SET ALTERNATE TO must
- *-- be used instead of LIST STATUS TO filename, since the
- *-- print destination would always show as a file. All
- *-- results that are returned are returned as character
- *-- types, including ones that return numbers (use VAL()
- *-- to look at/use returned value as a number).
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/01/1992 -- Original
- *-- : 10/26/1993 Angus Scott-Fleming
- *-- : replace cSafety w lSafety
- *-- : upper-case cStart
- *-- : minor bug fixes as noted by && <date>
- *-- Calls.......: TempFile() Function in FILES.PRG
- *-- TextLine() Function in FILES.PRG
- *-- AAppend() Function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: GetInfo(<cKeyWord>,[<cKeyWord2>])
- *-- Example.....: ? GetInfo("F5")
- *-- Returns.....: Character expression
- *-- Parameters..: cKeyWord = Item you are looking for status of,
- *-- options listed return the following:
- *-- WORK Number of current work area - whether
- *-- or not database is in use
- *-- PRINT Current printer destination (PRN, NUL,
- *-- LPT1, COM1) as set by SET PRINTER TO.
- *-- ERROR Error condition set by ON ERROR
- *-- ESCAPE Escape condition set by ON ESCAPE
- *-- F2 to F10, Ctrl-F1 to Ctrl-F10, Shift-F1
- *-- to Shift-F10
- *-- The current setting of each key
- *-- as set by SET FUNCTION <label> TO
- *-- OR
- *-- cKeyWord, cKeyWord2 = Items you are checking the
- *-- status of, options return the following:
- *-- PAGE,LINE Line number specified by ON PAGE AT
- *-- LINE in the page handling routine
- *-- HANDLE,<filename> The handle number of the low-
- *-- level file specified by <filename>
- *-- NAME,<filehandle> The file name of the low-
- *-- level file specified by <filehandle>
- *-- MODE,<filehandle> The privilege of the low-
- *-- level file specified by <filehandle>
- *----------------------------------------------------------------------
-
- parameters cKeyWord, cKeyWord2
- private cKey, l2Parms, cStart, lSafety, cTempTxt, nLines, cTmpArray
-
- cKey = upper(m->cKeyWord)
- l2Parms = (pcount() = 2)
-
- do case
- case m->cKey = "CTRL-" .or. m->cKey = "SHIFT" .or. ;
- (","+m->cKey+"," $ ",F2,F3,F4,F5,F6,F7,F8,F9,F10,")
- cStart = m->cKey + space(9 - len(m->cKey))+"-"
-
- case m->cKey = "PRINT"
- cStart = "Print Destination:"
-
- case m->cKey = "WORK"
- cStart = "Current work area ="
- if "" <> dbf()
- RETURN select(alias())
- endif
-
- case m->cKey = "ERROR"
- cStart = "On Error:"
-
- case m->cKey = "ESCAPE"
- cStart = "On Escape:"
-
- case m->cKey = "PAGE"
- cStart = "On Page At Line"
-
- case m->cKey = "HANDLE" .or. m->cKey = "NAME" .or. ;
- m->cKey = "MODE"
- cStart = "Low level files opened"
-
- otherwise && none of the above
- RETURN ""
-
- endcase
-
- cTempTxt = TempFile()
- *-- get status info (into a temp file), which will then be parsed to
- *-- extract information requested ...
- set console off
- set alternate to &cTempTxt.. && create file without extension
- && double 'dot' is required
- set alternate on
- list status
- close alternate
- set console on
-
- nLines = TextLine(m->cTempTxt)
- aTmpArray = right(m->cTempTxt,8)
- cTmp = AAppend(m->cTempTxt,m->aTmpArray)
- nHandle = fopen(m->cTempTxt,"R")
- cResult = ""
-
- nX = 1
- cStart = upper(m->cStart) && Tue 10-26-1993 upper case
- nStartLen = len(m->cStart) && Tue 10-26-1993 pre-load LEN
- do while m->nX <= m->nLines
- if upper(left(&aTmpArray.[m->nX],m->nStartLen)) = m->cStart
- cResult = ltrim(substr(&aTmpArray.[m->nX],m->nStartLen+1))
- exit
- endif
- nX = m->nX + 1
- enddo
-
- *-- 2 parameters?
- if m->l2Parms .and. "" # m->cResult
- do case
- case m->cKey = "PAGE"
- if upper(m->cKeyWord2) = "LINE"
- cResult = left(m->cResult,at(" ",m->cResult) - 1)
- else
- cResult = substr(m->cResult,at(" ",m->cResult) + 1)
- endif
-
- case m->cKey = "HANDLE" .or. m->cKey = "NAME" .or. ;
- m->cKey = "MODE"
- cResult = ""
- nX = m->nX + 2
- do while val(&aTmpArray.[m->nX]) <> 0
- do case
- case m->cKey = "HANDLE" .and. ;
- upper(m->cKeyWord2) $ &aTmpArray.[m->nX]
- cResult = str(val(&aTmpArray.[m->nX]))
-
- case m->cKey = "NAME" .and. ;
- m->cKeyWord2 = val(&aTmpArray.[m->nX])
- cResult = substr(&aTmpArray.[m->nX],10,40)
-
- case m->cKey = "MODE" .and. ;
- m->cKeyWord2 = val(&aTmpArray.[m->nX])
- cResult = substr(&aTmpArray.[m->nX],50,5)
- endcase
- if "" <> m->cResult
- exit
- endif
- nX = m->nX + 1
- enddo
- endcase
- endif
-
- release &aTmpArray.
- nClose = fclose(m->nHandle)
- lSafety = set ("safety") = "ON" && Tue 10-26-1993
- set safety off
- erase (m->cTempTxt + ".")
- if lSafety && Tue 10-26-1993 replace
- set safety ON && the dreaded macro expansion
- endif
- cResult = ltrim(rtrim(m->cResult))
-
- RETURN iif(right(m->cResult,1) = ":",;
- left(m->cResult,len(m->cResult)-1),m->cResult)
- *-- EoF: GetInfo()
-
- FUNCTION TextLine
- *----------------------------------------------------------------------
- *-- Programmer..: Adam L. Menkes (Borland Technical Support)
- *-- Date........: 04/01/1992
- *-- Notes.......: Returns the number of lines of text in an ASCII Text
- *-- File Taken from TechNotes, April, 1992
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/01/1992 -- Original
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: TextLine(<cTextFile>)
- *-- Example.....: ?TextLine("CONFIG.DB")
- *-- Returns.....: Number of lines
- *-- Parameters..: cTextFile = name of file
- *----------------------------------------------------------------------
-
- parameter cTextFile
- private nLines, nHandle, cTemp, nClose
-
- nLines = 0
- if file(m->cTextFile) && if it exists ...
- nHandle = fopen(m->cTextFile,"R")
- do while .not. feof(m->nHandle)
- cTemp = fgets(m->nHandle,254)
- nLines = m->nLines + 1
- enddo
- nClose = fclose(m->nHandle)
- endif
-
- RETURN m->nLines
- *-- EoF: TextLine()
-
- FUNCTION TLine
- *----------------------------------------------------------------------
- *-- Programmer..: Adam L. Menkes (Borland Technical Support)
- *-- Date........: 04/01/1992
- *-- Notes.......: Returns a specific line in an ASCII Text File. This
- *-- is similar to the way MLINE() works on a memo field.
- *-- Taken from TechNotes April, 1992.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/01/1992 -- Original
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: TLine(<cTextFile>,<nLine>)
- *-- Example.....: ?TLine("CONFIG.DB",20)
- *-- Returns.....: Character expression - specified line of text file.
- *-- Parameters..: cTextFile = name of text file
- *-- nLine = line to return from text file
- *----------------------------------------------------------------------
-
- parameters cTextFile, nLine
- private cText, nX, nHandle, nClose
-
- cText = ""
- nX = 1
- if file(m->cTextFile) && if file exists ...
- nHandle = fopen(m->cTextFile,"R")
- do while .not. feof(m->nHandle)
- cText = fgets(m->nHandle,254)
- if nX = m->nLine
- exit
- endif
- nX = m->nX + 1
- enddo
- nClose = fclose(m->nHandle)
- endif
-
- RETURN m->cText
- *-- EoF: TLine()
-
- FUNCTION TLineNo
- *----------------------------------------------------------------------
- *-- Programmer..: Adam L. Menkes (Borland Technical Support)
- *-- Date........: 04/01/1992
- *-- Notes.......: Returns the line number of the phrase you are
- *-- searching for in an ASCII Text File. This is similar
- *-- to dBASE's AT() function, but works on LINES rather
- *-- than CHARACTERS. Taken from TechNotes, April, 1992
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/01/1992 -- Original
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: TLineNo(<cTextFile>,<cLookup>,[<lCase>])
- *-- Example.....: ?TLineNo("CONFIG.DB","command",.f.)
- *-- Returns.....: numeric value (the line number containing the line
- *-- needed) returns -1 if not found
- *-- Parameters..: cTextFile = Name of ASCII Text File
- *-- cLookup = Text to search for ...
- *-- lCase = Case Sensitive? (Default is .F.)
- *----------------------------------------------------------------------
-
- parameters cTextFile, cLookup, lCase
- private cPhrase, nHandle, cText, nX, nClose
-
- if pCount() = 3 .and. m->lCase
- lCase = .t.
- cPhrase = m->cLookup
- else
- lCase = .f.
- cPhrase = upper(m->cLookup)
- endif
-
- cText = ""
- nX = 1
- if file(m->cTextFile)
- nHandle = fopen(m->cTextFile,"R")
- do while .not. feof(m->nHandle)
- cText = fgets(m->nHandle,254)
- if at(m->cPhrase,iif(m->lCase,m->cText,upper(m->cText))) > 0
- nClose = fclose(m->nHandle)
- RETURN m->nX
- endif
- nX = m->nX + 1
- enddo
-
- nClose = fclose(m->nHandle)
- endif
-
- RETURN -1
- *-- EoF: TLineNo()
-
- FUNCTION TempFile
- *----------------------------------------------------------------------
- *-- Programmer..: Adam L. Menkes (Borland Technical Support)
- *-- Date........: 04/01/1992
- *-- Notes.......: Returns a random filename.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/01/1992 -- Original
- *-- Calls.......: TempDir() Function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: TempFile([cFileExt])
- *-- Example.....: cVarFile = TempFile("$XY")
- *-- Returns.....: Filename
- *-- Parameters..: cFileExt = optional parameter - allows you to assign
- *-- file extension to the end of the filename.
- *----------------------------------------------------------------------
-
- parameters cFileExt
-
- RETURN TempDir()+"TMP"+right(ltrim(str(rand(-1)*10000000)),5);
- +iif(pcount() = 0 .or. "" = m->cFileExt,"","."+m->cFileExt)
- *-- EoF: TempFile()
-
- FUNCTION TempDir
- *----------------------------------------------------------------------
- *-- Programmer..: Adam L. Menkes (Borland Technical Support)
- *-- Date........: 04/01/1992
- *-- Notes.......: Returns path of temporary directory as set from DOS
- *-- (i.e., SET DBTMP= ...) Taken from TechNotes, April,92
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/01/1992 -- Original
- *-- Calls.......: GetEnv() Function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: TempDir()
- *-- Example.....: ?TempDir()
- *-- Returns.....: Path of temporary directory
- *-- Parameters..: None
- *----------------------------------------------------------------------
-
- cTempDir = iif("" <> GetEnv("DBTMP"),GetEnv("DBTMP"),GetEnv("TMP"))
-
- RETURN m->cTempDir+iif(right(m->cTempDir,1)<> "\" .and.;
- left(os(),3) = "DOS" .and. .not. "" = m->cTempDir,"\","")
- *-- EoF: TempDir()
-
- FUNCTION DirList
- *----------------------------------------------------------------------
- *-- Programmer..: Oktay Amiry (Borland Technical Support)
- *-- Date........: 02/01/1993
- *-- Notes.......: Used to display a popup of the hierarchical structure
- *-- of directories. With this you can select a directory
- *-- from the popup.
- *-- DirList() returns a DOS Error Number if it encounters
- *-- one, or a -1 if it fails to perform its task. It
- *-- Originally Printed in TechNotes, February 1993
- *-- ************************************************
- *-- *** REQUIRES DOS TREE COMMAND BE IN DOS PATH ***
- *-- ************************************************
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 02/01/1993 -- Original Release
- *-- Calls.......: WhatDir Procedure in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: DirList([<cDrive>])
- *-- Example.....: ?DirList() or
- *-- ?DirList("A:")
- *-- Returns.....: See above
- *-- Parameters..: cDrive = Optional Parameter to list a specific drive
- *-- instead of the default.
- *----------------------------------------------------------------------
-
- parameters cDrive
-
- *-- deal with possible errors
- do case
- case .not. "DOS" $ UPPER(OS()) && gotta be DOS, not UNIX
- RETURN "Incompatible operating system"
- case pcount() # 0 .and. type("cDRIVE") # "C"
- RETURN "Invalid Parameter"
- case type("cDrive") = "C" .and. .not. isalpha(left(m->cDrive,1))
- RETURN "Invalid Parameter"
- endcase
-
- *-- deal with file already being there
- if file("DIRECT.XXX")
- erase direct.xxx
- endif
-
- *-- save screen and then clear whatever's on it
- save screen to sDirList
- clear
-
- *-- get the "message" color from the attributes ....
- cMsgColor = substr(set("ATTRIBUTE"),at(chr(38),set("ATTRIBUTE"))+3)
- cMsgColor = substr(m->cMsgColor,at(",",m->cMsgColor)+1)
- cMsgColor = substr(m->cMsgColor,at(",",m->cMsgColor)+1)
- cMsgColor = left(m->cMsgColor,at(",",m->cMsgColor)-1)
-
- *-- display message (slightly modified by KJM)
- @ 9,22 fill to 13,60 color n+/n && shadow
- @ 8,20 fill to 12,58 color &cMsgColor.
- @ 8,20 to 12,58 double color &cMsgColor.
- @10,22 say "The directory tree is being created" color &cMsgColor.
-
- *-- execute DOS RUN command, putting output into a text file
- if type("CDRIVE") = "L"
- * tree must be run in DOS directory or in DOS path
- nRun = run(.f.,"TREE \ > direct.XXX",.t.)
- else
- cDrive = left(m->cDrive,1)+":\"
- nRun = run(.f.,"TREE &cDrive. > direct.xxx",.t.)
- endif
-
- *-- error has occured of some sort -- return error number OR -1
- if m->nRun # 0 .or. .not. file("DIRECT.XXX")
- RETURN iif(m->nRun # 0,m->nRun, -1)
- endif
-
- *-- use low-level routines to go in and deal with the file ...
- nHandle = fopen("DIRECT.XXX","R") && open text file
- cMove = fGets(m->nHandle,":")
- if feof(m->nHandle)
- lClose = fClose(m->nHandle)
- erase direct.xxx
- restore screen from sDirList
- release screen sDirList
- RETURN - 1
- endif
- cMove = fSeek(m->nHandle,len(m->cMove)-1)
-
- *-- define the popup
- define popup pTree from 1,20
- nBar = 1
- do while .not. feof(m->nHandle)
- define bar nBar of pTree prompt space(2) ;
- + fGets(m->nHandle)+space(5)
- nBar = m->nBar + 1
- enddo
-
- *-- store path (bar) & location of ascii 195 (√) or 192 (¿) to array
- declare aTemp[m->nBar,2] && temp array
- nBar = 1
- cMove = fSeek(m->nHandle,0,0)
- cMove = fGets(m->nHandle,":")
- cMove = fSeek(m->nHandle,len(m->cMove) - 1)
- do while .not. feof(m->nHandle)
- cBar = trim(fGets(m->nHandle))
- store cBar to aTemp[m->nBar,1]
- store iif(at(chr(195),m->cBar) # 0, at(chr(195),m->cBar),;
- at(chr(192),m->cBar)) to aTemp[m->nBar,2]
- nBar = m->nBar + 1
- enddo
-
- *-- hokay ...
- clear
- cUser = ""
- *-- when user selects something, execute routine WhatDir ...
- on selection popup pTree do whatdir with bar(),m->cUser
- activate popup pTree
- release popup pTree
- lClose = fClose(m->nHandle)
- erase direct.xxx
- restore screen from sDirList
- release screen sDirList
-
- RETURN m->cUser
- *-- EoF: DirList()
-
- PROCEDURE WhatDir
- *----------------------------------------------------------------------
- *-- Programmer..: Oktay Amiry (Borland Technical Support)
- *-- Date........: 02/01/1993
- *-- Notes.......: Part of DIRLIST() above -- this is used to extract
- *-- out of the prompt from a popup, the directory a user
- *-- selected ... This routine should not be used on its
- *-- own ... it assumes too much (like array aTemp[] being
- *-- in existence, and such)
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 02/01/1993 -- Original Release
- *-- Calls.......: GRAt() Function in FILES.PRG
- *-- Called by...: DirList()
- *-- Usage.......: Do WhatDir with <nBar>,<cDir>
- *-- Example.....: Do WhatDir with bar(),cUser
- *-- Returns.....: Directory
- *-- Parameters..: nBar = bar number of popup
- *-- cDir = prompt from popup to extract data ...
- *----------------------------------------------------------------------
-
- parameters nBar, cDir
-
- if m->nBar # 1
- cDir = substr(aTemp[m->nBar,1],GRAt(aTemp[m->nBar,1])+1)
- nLevel = aTemp[m->nBar,2]
- nBar = m->nBar - 1
- do while m->nBar # 1
- if aTemp[m->nBar,2] < m->nLevel
- cDir = substr(aTemp[m->nBar,1],GRAt(aTemp[m->nBar,1])+1);
- +"\"+m->cDir
- nLevel = aTemp[m->nBar,2]
- endif
- nBar = m->nBar - 1
- enddo
- cDir = aTemp[1,1] + m->cDir
- else
- cDir = aTemp[1,1]
- endif
- deactivate popup
-
- RETURN
- *-- EoP: WhatDir
-
- FUNCTION GRAt
- *----------------------------------------------------------------------
- *-- Programmer..: Oktay Amiry (Borland Technical Support)
- *-- Date........: 02/01/1993
- *-- Notes.......: Graphic Reverse At -- Returns position of the first
- *-- graphic character from the right of the string.
- *-- Originally printed in TechNotes, February, 1993
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 02/01/1993 -- Original Release
- *-- Calls.......: None
- *-- Called by...: WhatDir
- *-- Usage.......: GRAt(<cString>)
- *-- Example.....: n = GRAt(cBar)
- *-- Returns.....: Numeric
- *-- Parameters..: cString = string to search
- *----------------------------------------------------------------------
-
- parameters cString
-
- nLen = len(m->cString)
- lFound = .f.
-
- do while m->nLen # 0
- cChar = substr(m->cString,m->nLen,1)
- if asc(m->cChar) > 175 .and. asc(m->cChar) < 224
- lFound = .t.
- exit
- endif
- nLen = m->nLen - 1
- enddo
-
- RETURN iif(m->lFound,m->nLen,-1)
- *-- EoF: GRAt()
-
- FUNCTION FF
- *----------------------------------------------------------------------
- *-- Programmer..: Oktay Amiry (Borland Technical Support)
- *-- Date........: 02/01/1993
- *-- Notes.......: This routine will search a disk and find all
- *-- occurences of a specified file or files. It will then
- *-- allow you to select said file.
- *-- Originally printed in TechNotes, February, 1993
- *-- *********************************
- *-- **** USES DOS ATTRIB COMMAND ****
- *-- *********************************
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 02/01/1993 -- Original Release
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: FF(<cFile>[,<cPath>])
- *-- Example.....: ?ff("*.dbf","c:\temp")
- *-- Returns.....: Selected File
- *-- Parameters..: cFile = Filename, or wildcard specification, allows
- *-- use of standard ? and * wildcards in the way
- *-- DOS has always used them.
- *-- cPath = Optional -- specified drive and directory.
- *-- If not used, this UDF will start the search
- *-- at the root of the default drive.
- *----------------------------------------------------------------------
-
- parameters cFile,cPath
-
- cCurDir = set("DIRECTORY")
-
- *-- deal with error messages
- do case
- case type("CFILE") # "C"
- RETURN "Invalid Parameter"
- case pcount() > 1 .and. type("CFILE") # "C"
- RETURN "Invalid Parameter"
- case pcount() > 1 .and. type("CFILE") = "C"
- lError = .f.
- on error lError = .t.
- set directory to &cPath.
- on error
- if m->lError
- RETURN "Invalid Drive\Directory"
- endif
- endcase
-
- if file("TEMP.XXX")
- erase temp.xxx
- endif
-
- *-- save screen so we can restore it, and clear ...
- save screen to sFF
- clear
-
- *-- get the "message" color from the attributes ....
- cMsgColor = substr(set("ATTRIBUTE"),at(chr(38),set("ATTRIBUTE"))+3)
- cMsgColor = substr(m->cMsgColor,at(",",m->cMsgColor)+1)
- cMsgColor = substr(m->cMsgColor,at(",",m->cMsgColor)+1)
- cMsgColor = left(m->cMsgColor,at(",",m->cMsgColor)-1)
-
- *-- display message
- @ 9,22 fill to 13,60 color n+/n && shadow
- @ 8,20 fill to 12,58 color &cMsgColor.
- @ 8,20 to 12,58 double color &cMsgColor.
- @10,22 say "The directories are being searched" color &cMsgColor.
-
- *-- if no path was given, run the DOS Attrib command on whole drive
- if type("CPATH") = "L"
- nDosF = run(.f.,"ATTRIB \&cFile. /s > temp.xxx | sort",.t.)
- else && run it on the path that was given ...
- nDosF = run(.f.,"ATTRIB &cFile. /s > temp.xxx | sort",.t.)
- endif
-
- *-- if there was an error ...
- if m->nDosF # 0 .or. .not. file("TEMP.XXX")
- set directory to &cCurDir.
- restore screen from sFF
- release screen sFF
- RETURN iif(m->nDosF # 0,m->nDosF,-1)
- endif
-
- *-- use LOWLEVEL routines to process the output of ATTRIB command
- nHandle = fopen("TEMP.XXX","R")
- cMove = fgets(m->nHandle,":")
- if feof(m->nHandle)
- lClose = fClose(m->nHandle)
- erase temp.xxx
- restore screen from sFF
- release screen sFF
- RETURN "File not found"
- endif
-
- *-- ok. Now we create the popup ...
- cMove = fseek(m->nHandle,0,0)
- nBar = 1
- define popup pFile from 1,1
- do while .not. feof(m->nHandle)
- cBar = trim(fgets(m->nHandle))
- cBar = space(2)+substr(m->cBar,at(":",m->cBar)-1)+space(5)
- define bar nBar of pFile prompt m->cBar
- nBar = m->nBar + 1
- enddo
-
- *-- what do we do with it?
- clear
- on selection popup pFile deactivate popup
- activate popup pFile
- cSelect = iif(.not. isblank(prompt()), ltrim(rtrim(prompt())),"")
-
- *-- cleanup
- release popup pFile
- lClose = fclose(m->nHandle)
- erase temp.xxx
- set directory to &cCurDir.
- restore screen from sFF
- release screen sFF
-
- RETURN m->cSelect
- *-- EoF: FF()
-
- FUNCTION MakeStr
- *----------------------------------------------------------------------
- *-- Programmer..: Angus Scott-Fleming (CIS: 75500,3223)
- *-- (from code published in DBA)
- *-- Date........: 11/25/1992
- *-- Notes.......: Creates an empty structure extended database
- *-- Written for.: dBASE IV 1.5+
- *-- Rev. History: 11/25/1992 - Rev A uses structure of currently open
- *-- database, if present
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: MakeStr(<cFileName.Ext>)
- *-- Example.....: lDummy = MakeStr("G_HELP.STR")
- *-- Returns.....: .F. if no file was created, .T. if one was
- *-- Parameters..: cFileName = Name of file to create
- *----------------------------------------------------------------------
-
- parameters cFileName
- private ALL
-
- if isblank(m->cFileName)
- return .F.
- endif
-
- if .not. isblank(alias())
- copy structure extended to &cFileName.
- else
- * code from DataBased Advisor to create an empty DBF
- nLoopCount = 1 && Loop counter
- nDim = 5 && Number of rows in the DBF structure array
-
- * Declare array with the structure of the "structure extended"
- * DBF file
- DECLARE aDbfStru[m->nDim,5]
-
- aDbfStru[1,1] = "FIELD_NAME" && field name
- aDbfStru[1,2] = "C" && field type
- aDbfStru[1,3] = 10 && field length
- aDbfStru[1,4] = 0 && number of decimal places
- aDbfStru[1,5] = "N" && MDX index tag
-
- aDbfStru[2,1] = "FIELD_TYPE"
- aDbfStru[2,2] = "C"
- aDbfStru[2,3] = 1
- aDbfStru[2,4] = 0
- aDbfStru[2,5] = "N"
-
- aDbfStru[3,1] = "FIELD_LEN"
- aDbfStru[3,2] = "N"
- aDbfStru[3,3] = 3
- aDbfStru[3,4] = 0
- aDbfStru[3,5] = "N"
-
- aDbfStru[4,1] = "FIELD_DEC"
- aDbfStru[4,2] = "N"
- aDbfStru[4,3] = 3
- aDbfStru[4,4] = 0
- aDbfStru[4,5] = "N"
-
- aDbfStru[5,1] = "FIELD_IDX"
- aDbfStru[5,2] = "C"
- aDbfStru[5,3] = 1
- aDbfStru[5,4] = 0
- aDbfStru[5,5] = "N"
-
- * Redirect printer output to a file
- SET PRINTER TO FILE (m->cFileName)
- SET PRINT ON
-
- * Write DBF file header
- * First byte (byte 0)- DBF file indicator
- ??? '{3}'
-
- * Creation date - bytes 1-3
- ??? CHR(VAL(RIGHT(STR(YEAR(DATE())),2))) + ;
- CHR(MONTH(DATE())) + CHR(DAY(DATE()))
-
- * Number of records in the file (zero) - bytes 1-3
- ??? REPLICATE('{0}',4)
-
- * Number of bytes in the header - bytes 8-9
- ??? '{193}{0}'
-
- * Number of bytes in the record (19) - bytes 10-11
- ??? '{19}{0}'
-
- * Bytes 12-31 of the header - not used here
- * Some appear to have constant value
- ??? REPLICATE('{0}',18)
- ??? '{57}{1}'
-
- * Field descriptor bytes - looping through the array
- * nDim times (5 in this case)
- * Field descriptors are each 32 bytes long
- DO WHILE m->nLoopCount <= m->nDim
-
- * Field name - bytes 0-10
- ??? aDbfStru[m->nLoopCount,1] +;
- REPLICATE('{0}', 11-LEN(TRIM(aDbfStru[m->nLoopCount,1])))
-
- * Field type - byte 11
- ??? aDbfStru[m->nLoopCount,2]
-
- * Bytes 12-15 - not used here
- ??? REPLICATE('{0}',2)
- ??? '{238}{85}'
-
- * Field length - byte 16
- ??? CHR(aDbfStru[m->nLoopCount,3])
-
- * Field decimal count - byte 17
- ??? IIF(aDbfStru[m->nLoopCount,4] > 0, ;
- CHR(aDbfStru[m->nLoopCount,4]), '{0}')
-
- * Bytes 18-19 - reserved
- ??? REPLICATE('{0}',2)
-
- * Byte 20 - work area ID. Let's use 1 for simplicity
- ??? '{1}'
-
- * Bytes 21-31 - MDX index tag flag and reserved bytes
- ??? IIF(aDbfStru[m->nLoopCount,5] $ 'YyTt', '{1}', '{0}')
- ??? REPLICATE('{0}',10)
-
- * Increment loop counter
- nLoopCount = m->nLoopCount + 1
- ENDDO
-
- * DBF file header terminator and EOF character - byte n+1
- ??? '{13}{26}'
-
- SET PRINTER TO
- SET PRINT OFF
- endif
- select (select())
- use &cFileName. exclusive
- zap
-
- RETURN .T.
- *-- EoF: MakeStr()
-
- FUNCTION RecChged
- *----------------------------------------------------------------------
- *-- Programmer..: Angus Scott-Fleming (CIS: 75500,3223)
- *-- Date........: 11/25/1992
- *-- Notes.......: Test field values against memory variables to see if
- *-- an on-screen display has changed from the disk-record
- *-- CHANGE() requires the existence of field _DBASELOCK
- *-- whereas RecChged does not.
- *-- Written for.: dBASE IV 1.1+
- *-- Rev. History: 11/25/1992 for dBase IV 1.5
- *-- 10/08/1992 don't test memo-fields
- *-- 06/09/1992 dropped PCount() for 4.11 use
- *-- 06/04/1992 skips _DBASELOCK field
- *-- 08/02/1993 minor tuning
- *-- Calls.......: FldCount() (1.1)
- *-- ExEqual() Function in STRINGS.PRG
- *-- Called by...: Any
- *-- Usage.......: RecChged(<cTable_Name>)
- *-- Example.....: if RecChged("mpl") .and. Confirm("Save?",.Y.)
- *-- Returns.....: .T. = record is changed .F. = record is not changed
- *-- Parameters..: cTable_Name = (OPTIONAL) alias of table to test
- *----------------------------------------------------------------------
-
- parameters ctable_name
- if empty(m->ctable_name)
- ctable_name = alias()
- endif
- n = 1
- do while m->n <= fldcount(m->ctable_name)
- test_field = field(m->n,m->ctable_name)
- test_disk = "&ctable_name.->&test_field."
- * Thu 06-04-1992 don't test _DBASELOCK field
- * Thu 10-08-1992 check for existence of the field in the table
- * skip check for memo fields
- if .not. upper(test_field) = "_DBASELOCK" .and. ;
- .not. type("&test_disk.") $ "MU" .and. ;
- .not. type("m->&test_field.") ="U" .and. ;
- .not. ExEqual(m->&test_field.,&test_disk.)
- return .T.
- endif
- n = m->n + 1
- enddo
-
- RETURN .F.
- *-- EoF: RecChged()
-
- FUNCTION CopyFile
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153)
- *-- Date........: 04/26/1993
- *-- Notes.......: Copies a database plus its production index (if it
- *-- has one), and the DBT file if it exists as well.
- *-- Use this instead of the COPY TO... WITH PRODUCTION
- *-- command. Because it uses the COPY FILE command (a
- *-- file-to-file copy) instead of the COPY TO command (a
- *-- record-by-record copy), this is much faster.
- *-- The DBF must be closed when you use this UDF.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: MdxPoint() Function in FILES.PRG
- *-- DbfName() Function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: CopyFile("<cOldFile>","<cNewFile>")
- *-- Example.....: CopyFile("FRED","MARY")
- *-- Returns.....: nError - 0 if copy operation worked okay.
- *-- 1 if file to be copied didn't exist.
- *-- Parameters..: cOldFile - DBF file to be copied
- *-- cNewFile - Name for copy of DBF
- *----------------------------------------------------------------------
-
- parameters cOldFile,cNewFile
- private cOldFile, cNewFile, lOpen, nRec, cTag, cAlias, nError
-
- nError = 0
-
- *-- Check if database actually exists
- if file(m->cOldFile + ".DBF")
-
- *-- Copy the file
- copy file m->cOldFile + ".DBF" to m->cNewFile + ".DBF"
-
- *-- Copy its MDX file
- if file(m->cOldFile + ".MDX")
-
- copy file m->cOldFile + ".MDX" to m->cNewFile + ".MDX"
- *-- Update the hard-coded database reference in the MDX header
- xJunk = MdxPoint(m->cNewFile)
-
- endif
-
- *-- Copy its memo file
- if file(m->cOldFile + ".DBT")
-
- copy file m->cOldFile + ".DBT" to m->cNewFile + ".DBT"
-
- endif
-
- else
- nError = 1
-
- endif
-
- RETURN (m->nError)
- *-- EoF: CopyFile()
-
- FUNCTION CopyFil1
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153)
- *-- Date........: 04/26/1993
- *-- Notes.......: Copies a database plus its production index (if it
- *-- has one), and the DBT file if it exists as well.
- *-- Based on CopyFile().
- *-- With this version, it doesn't matter whether the
- *-- file you're copying is open or closed. If it's open,
- *--
- *-- * current index order
- *-- * alias
- *-- * record pointer
- *--
- *-- will all be retained.
- *-- You must SET DBTRAP OFF before calling this routine
- *-- from a program or the dot prompt.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: MdxPoint() Function in FILES.PRG
- *-- DbfName() Function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: CopyFile("<cOldFile>","<cNewFile>")
- *-- Example.....: CopyFile("FRED","MARY")
- *-- Returns.....: nError - 0 if copy operation worked okay.
- *-- 1 if file to be copied didn't exist.
- *-- Parameters..: cOldFile - DBF file to be copied
- *-- cNewFile - Name for copy of DBF
- *----------------------------------------------------------------------
-
- parameters cOldFile,cNewFile
- private cOldFile, cNewFile, lOpen, nRec, cTag, cAlias, nError
-
- lOpen = .F.
- nError = 0
-
- *-- Check whether database exists
- if file(m->cOldFile + ".DBF")
-
- *-- If database is currently open, save info about it
- if DbfName() = upper(m->cOldFile)
- nRec = recno()
- cTag = tag()
- cAlias = alias()
- lOpen = .T.
- use
- endif
-
- *-- Copy the database
- copy file m->cOldFile + ".DBF" to m->cNewFile + ".DBF"
-
- *-- Copy its MDX
- if file(m->cOldFile + ".MDX")
-
- copy file m->cOldFile + ".MDX" to m->cNewFile + ".MDX"
- *-- Update the hard-coded database reference in the MDX header
- xJunk = MdxPoint(m->cNewFile)
-
- endif
-
- *-- Copy its memo file
- if file(m->cOldFile + ".DBT")
-
- copy file m->cOldFile + ".DBT" to m->cNewFile + ".DBT"
-
- endif
-
- *-- If file was originally open, reopen it and restore its state
- if m->lOpen
- use (m->cOldFile) ALIAS &cAlias.
- if "" <> m->cTag
- set order to (m->cTag)
- endif
- go m->nRec
- endif
-
- else
- m->nError = 1
-
- endif
-
- RETURN (m->nError)
- *-- EoF: CopyFil1()
-
- FUNCTION RenFile
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153)
- *-- Date........: 04/26/1993
- *-- Notes.......: Renames a .DBF file and its production index and
- *-- memo files (if they exist) and correctly updates
- *-- the .MDX header.
- *-- The DBF must be closed before using this UDF.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: MdxPoint() Function in FILES.PRG
- *-- DbfName() Function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: RenFile("<cOldFile>","<cNewFile>")
- *-- Example.....: RenFile("FRED","MARY")
- *-- Returns.....: nError - 0 if renaming operation went okay.
- *-- 1 if file to be renamed didn't exist.
- *-- Parameters..: cOldFile - Current database name
- *-- cNewFile - New name for database
- *----------------------------------------------------------------------
-
- parameters cOldFile,cNewFile
- private cOldFile, cNewFile, lOpen, nError, nRec, cTag, cAlias, xJunk
-
- nError = 0
-
- *-- Check whether database exists
- if file(m->cOldFile + ".DBF")
-
- *-- Rename it
- rename m->cOldFile + ".DBF" to m->cNewFile + ".DBF"
-
- *-- Rename its MDX
- if file(m->cOldFile + ".MDX")
-
- rename m->cOldFile + ".MDX" to m->cNewFile + ".MDX"
- *-- Update the hard-coded database reference in the MDX header
- xJunk = MdxPoint(m->cNewFile)
-
- endif
-
- *-- Rename its memo file
- if file(m->cOldFile + ".DBT")
-
- rename m->cOldFile + ".DBT" to m->cNewFile + ".DBT"
-
- endif
-
- else
- nError = 1
-
- endif
-
- RETURN (m->nError)
- *-- EoF: RenFile()
-
- FUNCTION RenFile1
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153)
- *-- Date........: 04/26/1993
- *-- Notes.......: Renames a .DBF file and its production index and memo
- *-- files (if they exist) and correctly updates the .MDX
- *-- header. This is a variant of RenFile().
- *-- In this version, it doesn't matter whether the
- *-- database is open or closed when you call the UDF. If
- *-- it is open, the
- *--
- *-- * current index order
- *-- * record pointer
- *--
- *-- will be restored after the renaming.
- *-- You must SET DBTRAP OFF before calling this UDF.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: MdxPoint() Function in FILES.PRG
- *-- DbfName() Function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: RenFile("<cOldFile>","<cNewFile>")
- *-- Example.....: RenFile("FRED","MARY")
- *-- Returns.....: nError - 0 if renaming operation went okay.
- *-- 1 if file to be renamed didn't exist.
- *-- Parameters..: cOldFile - Current database name
- *-- cNewFile - New name for database
- *----------------------------------------------------------------------
-
- parameters cOldFile,cNewFile
- private cOldFile, cNewFile, lOpen, nError, nRec, cTag, xJunk
-
- lOpen = .F.
- nError = 0
-
- *-- Check if database exists
- if file(m->cOldFile + ".DBF")
-
- *-- If database is currently open, save record pointer
- *-- and index order
- if DbfName() = upper(m->cOldFile)
- nRec = recno()
- cTag = tag()
- lOpen = .T.
- use
- endif
-
- *-- Rename database
- rename m->cOldFile + ".DBF" to m->cNewFile + ".DBF"
-
- *-- Rename its MDX
- if file(m->cOldFile + ".MDX")
-
- rename m->cOldFile + ".MDX" to m->cNewFile + ".MDX"
- *-- Update the hard-coded database reference in the MDX header
- xJunk = MdxPoint(m->cNewFile)
-
- endif
-
- *-- Rename its memo file
- if file(m->cOldFile + ".DBT")
-
- rename m->cOldFile + ".DBT" to m->cNewFile + ".DBT"
-
- endif
-
- *-- If file was originally open, reopen it and restore its state
- if m->lOpen
- use (m->cNewFile)
- if "" <> m->cTag
- set order to (m->cTag)
- endif
- go m->nRec
- endif
-
- else
- nError = 1
-
- endif
-
- RETURN (m->nError)
- *-- EoF: RenFile1()
-
- FUNCTION DelFile
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153)
- *-- Date........: 04/26/1993
- *-- Notes.......: Deletes a database, its production index and its memo
- *-- file (if there is one) in one fell swoop.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: DelFile("<cDbfName>")
- *-- Example.....: DelFile("FRED")
- *-- Returns.....: nError - 0 if file deletion went okay
- *-- - 1 if file to be deleted didn't exist.
- *-- Parameters..: cDbfName - Name of the database you wish to delete.
- *----------------------------------------------------------------------
- parameters cDbfName
- private cDbfName, cMdxName, cDbtName, nError
-
- cMdxName = m->cDbfName + ".MDX"
- cDbtName = m->cDbfName + ".DBT"
- cDbfName = m->cDbfName + ".DBF"
- nError = 0
-
- *-- Check database exists
- if file(m->cDbfName)
-
- *-- Delete database
- delete file (m->cDbfName)
-
- *-- Delete its MDX
- if file(m->cMdxName)
- delete file (m->cMdxName)
- endif
-
- *-- Delete its memo file if any
- if file(m->cDbtName)
- delete file (m->cDbtName)
- endif
-
- else
-
- nError = 1
-
- endif
-
- RETURN (m->nError)
- *-- EoF: DelFile()
-
- FUNCTION DelMdx
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153)
- *-- Date........: 04/26/1993
- *-- Notes.......: Deletes a production index file, correctly updating
- *-- the production index byte in the DBF header, so you
- *-- avoid the "Production index not found" message.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: DelMdx("<cMdx>")
- *-- Example.....: DelMdx("fred")
- *-- Returns.....: nError = 0 if deletion is okay
- *-- 1 if file doesn't exist
- *-- Parameters..: cMdx = Production MDX file to delete
- *----------------------------------------------------------------------
- parameters cMdx
- private cMdx, cMdxName, cDbfName, nHandle, nError, xJunk
-
-
- cMdxName = m->cMdx + ".MDX"
- cDbfName = m->cMdx + ".DBF"
- nError = 0
-
- *-- Check if file exists
- if file(m->cMdxName)
-
- *-- Delete MDX file
- delete file (m->cMdxName)
-
- *-- Update MDX byte in DBF header, indicating there is no longer
- *-- an MDX for this database.
- nHandle = fopen((m->cDbfName),"rw")
- xJunk = fseek(m->nHandle,28,0)
- xJunk = fwrite(m->nHandle,chr(0))
- xJunk = fclose(m->nHandle)
-
- else
-
- nError = 1
-
- endif
-
- RETURN ("")
- *-- EoF: DelMdx()
-
- FUNCTION RestMdx
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153)
- *-- Date........: 04/26/1993
- *-- Notes.......: Restores a pointer to an (existing) production MDX
- *-- file in the DBF header. Only really needed if you
- *-- make a mess using the DelMdx() function.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: RestMdx("<cMdx>")
- *-- Example.....: RestMdx("FRED")
- *-- Returns.....: nError - 0 if pointer restoration went okay
- *-- 1 if the MDX didn't exist
- *-- Parameters..: cMdx - MDX/DBF file name.
- *----------------------------------------------------------------------
-
- parameters cMdx
- private cMdxName, cDbfName, nHandle, xJunk, nError
-
- cMdxName = m->cMdx + ".MDX"
- cDbfName = m->cMdx + ".DBF"
-
- if file(m->cMdxName)
-
- *-- Update MDX byte in DBF header, indicating there is an
- *-- MDX for this database.
- nHandle = fopen((m->cDbfName),"rw")
- xJunk = fseek(m->nHandle,28,0)
- xJunk = fwrite(m->nHandle,chr(1))
- xJunk = fclose(m->nHandle)
- nError = 0
-
- else
-
- nError = 1
-
- endif
-
- RETURN (m->nError)
- *-- EoF: RestMdx()
-
- FUNCTION MdxPoint
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153)
- *-- Date........: 04/26/1993
- *-- Notes.......: Changes the hard-coded DBF name in an MDX file header
- *-- (either a production or non-production MDX).
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: None
- *-- Called by...: Any (Specifically CopyFile() and RenFile())
- *-- Usage.......: MdxPoint("<cDbfName>", "<cMdx>")
- *-- Example.....: MdxPoint("FRED")
- *-- MdxPoint("FRED","FULLNAME")
- *-- Returns.....: None
- *-- Parameters..: cDbfName - The name of the DBF to be hard-coded into
- *-- the MDX header.
- *-- cMdx - The name of the MDX file, if it's a
- *-- non-production MDX (omit this parameter
- *-- completely if it's a production MDX).
- *----------------------------------------------------------------------
-
- parameters cDbfName, cMdx
- private nPadl, cDbfName, nHandle, xJunk, n
-
- *-- Find out how long the DBF filename is and set padding length
- nPadl = 8 - len(m->cDbfName)
- cDbfName = upper(m->cDbfName)
-
- *-- Check how many parameters have been passed: 1 means its a
- *-- production index, 2 is a non-production index
- if pcount() < 2
-
- nHandle = fopen((m->cDbfName)+".MDX","rw")
-
- else
-
- nHandle = fopen((m->cMdx)+".MDX","rw")
-
- endif
-
- *-- Position file pointer to Byte 4, which is start of hard-coded
- *-- DBF name in MDX header
- xJunk = fseek(m->nHandle,4,0)
- *-- Write the new DBF filename into the header
- xJunk = fwrite(m->nHandle,(m->cDbfName))
-
- n = 0
-
- do while m->n < m->nPadl
-
- *-- Pad filename out to 8 characters in header, using nulls
- xJunk = fwrite(m->nHandle,chr(0))
- n = m->n + 1
-
- enddo
-
- xJunk = fclose(m->nHandle)
-
- RETURN ("")
- *-- EoF: MdxPoint()
-
- FUNCTION DbfName
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153)
- *-- Date........: 04/26/1993
- *-- Notes.......: Strips the 8-character DBF filename out of the full
- *-- pathname returned by the dbf() function. Works on the
- *-- database in USE in the current workarea.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: None
- *-- Called by...: Any (Specifically CopyFile() and RenFile()).
- *-- Usage.......: DbfName()
- *-- Example.....: DbfName()
- *-- Returns.....: cName = 8-character filename of DBF.
- *-- Parameters..: None
- *----------------------------------------------------------------------
- private cFullPath, cName
-
- cFullPath = set("FULLPATH")
- set fullpath off
-
- *-- Check if a database is open in the current workarea
- if "" <> dbf()
-
- *-- Strip the filename out of the full pathname
- cName = ( substr( dbf(), 3, at( ".", dbf() ) - 3 ) )
-
- else
-
- cName = ""
-
- endif
-
- set fullpath &cFullPath.
-
- RETURN (m->cName)
- *-- EoF: DbfName()
-
- FUNCTION MdxGauge
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153)
- *-- Date........: 04/26/1993
- *-- Notes.......: Indexes a database, showing a 'fuel-gauge' style
- *-- progress indicator during the process.
- *-- You must SET DBTRAP OFF in the calling routine or at
- *-- the dot prompt.
- *-- This routine slows down indexing, but allows the user
- *-- to know what's going on.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: Gauge(), DelGauge()
- *-- Called by...: Any
- *-- Usage.......: MdxGauge("<cDataFile>","<cIndexExp>","<cMTag>",;
- *-- "<cMdxName>","<cClr>",<nURow>,<nLCol>)
- *-- Example.....: MdxGauge("FRED","upper(LNAME)+upper(FNAME)",;
- *-- "FULLNAME","",0,0)
- *--
- *-- This example indexes FRED.DBF on the uppercase last
- *-- and firstnames, to the production MDX with a tagname
- *-- of FULLNAME. It also uses your current default color
- *-- scheme, and positions the fuel gauge at 0,0.
- *--
- *-- MdxGauge("FRED","substr(LNAME,5)","SHORTNAME",;
- *-- "OTHERS","r+/b,r+/b,b+/w";10,15)
- *--
- *-- This example indexes FRED.DBF on the first five
- *-- characters of the lastname to a non-production MDX
- *-- called OTHERS, using the tagname SHORTNAME. It sets
- *-- the colors of the fuel- gauge and the fuel-gauge
- *-- frame, and positions the gauge starting at 10,15.
- *-- Returns.....: nError = 0 if MDX header was updated correctly
- *-- = 1 if MDX header couldn't be updated
- *-- Parameters..: cDataFile = DBF to be indexed
- *-- cMdxExpr = Indexing expression
- *-- cMdxTag = Index TAG name
- *-- cMdxName = MDX name - only needed if using a
- *-- non-production MDX.
- *-- cClr = Colors for fuel gauge. You can include
- *-- standard, enhanced and frame colors in
- *-- the string. If you don't include a
- *-- color string, the UDF will use the
- *-- current colors.
- *-- nURow = Starting row for fuel gauge on screen.
- *-- Must be less than 20 - if not, the
- *-- program will make nURow = 19.
- *-- nLCol = Starting column for fuel gauge.
- *-- Must be less than 26 - if not, the
- *-- program will make nLCol = 25.
- *----------------------------------------------------------------------
-
- parameters cDbfName, cMdxExpr, cMdxTag, cMdxName, cClr, nURow, nLCol
- private nBarLen, cBarPad, cIndex, nError, nRecInt, nBarFull
-
- use (m->cDbfName)
-
- cStatus = set("STATUS")
- cSafety = set("SAFETY")
- cTalk = set("TALK")
- set status off
- set safety off
- set talk off
-
- cMdxExpr = upper(m->cMdxExpr)
- cMdxTag = upper(m->cMdxTag)
-
- *-- If color parameter is blank, use default color scheme
- if cClr <> ""
-
- cClr = SET("ATTR")
-
- endif
-
-
- if m->nURow > 19
-
- nURow = 19
-
- endif
-
- if m->nLCol > 25
-
- nLCol = 25
-
- endif
-
- *-- Determine width of fuel-gauge
- if reccount() > 50
-
- nRecInt = int(reccount()/50)
- nBarLen = int( reccount() / m->nRecInt )
-
- else
-
- nBarLen = reccount() + 1
-
- endif
-
- cBarPad = space(round((m->nBarLen-16)/3,0))
-
- clear
-
- *-- Display fuel-gauge window and empty gauge
- define window wGauge from m->nURow, m->nLCol;
- to m->nURow+5,m->nBarLen+m->nLCol+2 color &cClr.
- activate window wGauge
-
- @ 0,0 say "Indexing " + Dbf()
- @ 1,0 say "0% " + m->cBarPad + "25% " + m->cBarPad + "75% " + ;
- m->cBarPad + "100%"
- @ 2,0 say replicate( chr(219), m->nBarlen )
- @ 2,0 say ""
-
- *-- Check if it's a production index or not, and then
- *-- use the appropriate index expression. The FOR condition
- *-- in the expression "fills up" the fuel gauge.
- if "" = m->cMdxName
-
- index on &cMdxExpr. tag &cMdxTag. for Gauge()
-
- else
- index on &cMdxExpr. tag &cMdxTag. of &cMdxName. for Gauge()
-
- endif
-
- *-- Clean up
- clear
- @ 2,0 say "Closing files..."
- nError = 0
- cIndex = mdx()
- use
-
- *-- Call UDF to delete reference to Gauge() UDF from MDX header
- nError = DelGauge(m->cIndex, m->cMdxTag)
-
- deactivate window wGauge
-
- set status &cStatus.
- set safety &cSafety.
- set talk &cTalk.
-
- RETURN(m->nError)
- *-- EoF: MdxGauge()
-
- FUNCTION Gauge
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153)
- *-- Date........: 04/26/1993
- *-- Notes.......: Routine used by MdxGauge() to "fill up" the fuel-
- *-- gauge on screen during indexing.
- *-- It is called from an indexing "FOR" expression, and
- *-- always returns .T. to include all records in index.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: None
- *-- Called by...: MdxGauge() Function in FILES.PRG
- *-- Usage.......: Gauge()
- *-- Example.....: Gauge()
- *-- Returns.....: .T.
- *-- Parameters..: None
- *----------------------------------------------------------------------
-
- *-- Every time 2% of the file or so is indexed...
- if reccount() > 50
-
- if mod( recno(), m->nRecInt ) = 0
-
- *-- Display a solid bar character to "fill up" the gauge
- ?? chr(177)
-
- endif
-
- else
-
- ?? chr(177)
-
- endif
-
- RETURN(.T.)
- *-- EoF: Gauge()
-
- FUNCTION DelGauge
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153)
- *-- Date........: 04/26/1993
- *-- Notes.......: Deletes all reference to the Gauge() UDF from within
- *-- an MDX header file.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: FindTagExp() Function in FILES.PRG
- *-- Called by...: MdxGauge()
- *-- Usage.......: DelGauge("<cMdx>","<cTag>")
- *-- Example.....: DelGauge("FRED","upper(LASTNAME)+upper(FIRSTNAME)")
- *-- Returns.....: nError - Error code.
- *-- 0 if the UDF managed to delete the Gauge()
- *-- reference in the header.
- *-- 1 if the UDF failed (it couldn't find the
- *-- Gauge() reference.
- *-- Parameters..: cMdx = MDX file to search.
- *-- cTag = TAG expression to search for.
- *----------------------------------------------------------------------
- parameters cMdx, cTag
- private nHandle, nTagExp, nForFlag, nForExp, nError, n, xJunk
-
- *-- Open the MDX file
- nHandle = fopen(m->cMdx,'rw')
-
- *-- Find the information about the TAG in the MDX header
- nTagExp = FindTagExp( m->nHandle, m->cTag )
- *-- Find the byte indicating whether a FOR clause was used
- *-- to create this particular TAG.
- nForFlag = m->nTagExp + 245
- *-- Find the start of the FOR expression in the TAG information
- nForExp = m->nTagExp + 762
-
- *-- Place 00H in the byte indicating a FOR clause, to delete
- *-- reference to the FOR clause.
- xJunk = fseek( m->nHandle, m->nForFlag, 0 )
- xJunk = fwrite (m->nHandle, chr(0))
- *-- Positioning the pointer at the FOR clause in the TAG info.
- xJunk = fseek( m->nHandle, m->nForExp, 0 )
-
- *-- Check that we've found our UDF reference in the FOR clause
- *-- and, if so, delete the reference to the UDF by writing a
- *-- series of nulls to the file over the word "GAUGE()".
- if upper(fread(m->nHandle,7)) = 'GAUGE()'
-
- nError = 0
- xJunk = fseek( m->nHandle, m->nForExp, 0)
- n = 1
-
- do while m->n < 8
-
- xJunk = fwrite(m->nHandle,chr(0))
- n = m->n + 1
-
- enddo
-
- else
-
- nError = 1
-
- endif
-
- xJunk = Fclose(m->nHandle)
-
- RETURN (m->nError)
- *-- EoF: DelGauge()
-
- FUNCTION FindTagExp
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153) (dBase version)
- *-- Date........: 04/26/1993
- *-- Notes.......: Finds the starting position of a specific index TAG
- *-- expression within an MDX header.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: FLocate() Function in FILES.PRG
- *-- FReadI32() Function in FILES.PRG
- *-- Called by...: DelGauge()
- *-- Usage.......: FindTagExp(<nHandle>,"<cMdxTag>")
- *-- Example.....: FindTagExp( 5, "upper(LASTNAME)+upper(FIRSTNAME)" )
- *-- Returns.....: nTagExp - Starting position of the TAG expression
- *-- within the MDX header file.
- *-- Parameters..: nHandle = DOS file handle of an MDX file.
- *-- cMdxTag = MDX TAG expression.
- *----------------------------------------------------------------------
-
- parameters nHandle, cMdxTag
- private nJunk, nPos, nPoint, nTagExp
-
- *-- Shift pointer to byte 512 in the MDX file. At byte 512,
- *-- there's an array of TAG names.
- nJunk = fseek( m->nHandle, 512, 0 )
- *-- From there, locate our particular TAG in the array
- nPos = Flocate( m->nHandle, m->cMdxTag, .T. )
- *-- Back up and read the preceding 4 bytes, which are a pointer
- *-- to the file offset where the information about our TAG
- *-- is located in the MDX file.
- nJunk = fseek( m->nHandle, m->nPos - 4 )
- *-- Convert the 4-byte pointer to decimal
- nPoint = FreadI32( m->nHandle )
- *-- Return the starting position of the TAG info.
- nTagExp = fseek( m->nHandle, m->nPoint * 512 )
-
- RETURN( m->nTagExp )
- *-- EoF: FindTagExp()
-
- FUNCTION FLocate
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153) (dBase version)
- *-- Matt Whelan (Clipper version - not included here)
- *-- Date........: 04/26/1993
- *-- Notes.......: Finds a string within a file, starting from current
- *-- position of the file pointer (Operates using low-
- *-- level file functions).
- *-- Due to the 254-character limitation on dBase string
- *-- variables, this is not particularly fast on large
- *-- files as it must search through a 254-char buffer.
- *-- The Clipper version, which uses a 65,535-character
- *-- buffer, is much faster.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: FTell() Function in FILES.PRG
- *-- FLen() Function in FILES.PRG
- *-- Called by...: Any (Specifically FindTaxExp()).
- *-- Usage.......: FLocate(<nHandle>,"<cSearch>",<lWantUpper>)
- *-- Example.....: FLocate( 5, "Crabapple Cove", .T.)
- *-- Returns.....: nFoundPos - Starting position of the string in file
- *-- Parameters..: nHandle = DOS file handle
- *-- cSearch = Search string
- *-- lWantUpper = Whether you want the search string
- *-- first converted to uppercase.
- *----------------------------------------------------------------------
-
- parameters nHandle, cSearch, lWantUpper
- private cBuffer, nCurPos, nStartPos, nBuffSize, nFlength
- private nBufPos, cTxtBuff, nBuffOffset, nFoundPos, cAddBuf
-
- nFoundPos = -2
-
- *-- Convert search string to uppercase if required
- if pcount() = 2
-
- lWantUpper = .F.
-
- endif
-
- *-- If a valid file handle has been passed...
- if nHandle > 0
-
- *-- Store our current position in the file,
- *-- check the file length and then determine the
- *-- buffer size.
- nCurPos = Ftell( m->nHandle )
- nStartPos = m->nCurPos
- nFlength = Flen( m->nHandle )
- nBuffSize = min( 254, m->nFlength )
-
- *-- Now start reading characters into the buffer
- do while m->nCurPos < m->nFlength
-
- cBuffer = ""
-
- do while len(m->cBuffer) < m->nBuffSize
-
- cAddBuf = fread( m->nHandle, 1 )
-
- *-- If you read in a null, replace it in the buffer
- *-- by a space
- if chr(0) = m->cAddBuf
-
- cAddBuf = " "
-
- endif
-
- cBuffer = m->cBuffer + m->cAddBuf
-
- enddo
-
- if lWantUpper
-
- cBuffer = upper(m->cBuffer)
-
- endif
-
- *-- See if the search string is in the buffer
- nBufPos = at( m->cSearch, m->cBuffer )
-
- *-- and if it is, store its position in the file
- if nBufPos > 0
-
- nFoundPos = m->nCurPos + m->nBufPos - 1
- exit
-
- endif
-
- nCurPos = Ftell( m->nHandle )
-
- enddo
-
- if nFoundPos < 1
-
- nJunk = fseek( m->nHandle, m->nStartPos, 0 )
-
- else
-
- nJunk = fseek( m->nHandle, m->nFoundPos, 0 )
-
- endif
-
- endif
-
- RETURN( m->nFoundPos )
- *-- EoF: FLocate()
-
- FUNCTION FTell
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153)
- *-- Date........: 04/26/1993
- *-- Notes.......: A shorthand way of finding the current position of
- *-- file pointer in a file, without moving the pointer.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: None
- *-- Called by...: Any (specifically FLocate()).
- *-- Usage.......: FTell(<nHandle>)
- *-- Example.....: FTell(5)
- *-- Returns.....: Current position of pointer in a file.
- *-- Parameters..: nHandle = DOS file handle.
- *----------------------------------------------------------------------
-
- parameters nHandle
-
- RETURN( fseek( m->nHandle, 0, 1 ) )
- *-- EoF: FTell()
-
- FUNCTION FLen
- *----------------------------------------------------------------------
- *-- Programmer..: Rose Vines (CIS: 100026,3153)
- *-- Date........: 04/26/1993
- *-- Notes.......: Finds length (in bytes) of a file and then returns
- *-- the file pointer to byte 0.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 -- Original
- *-- Calls.......: None
- *-- Called by...: Any (specifically FLocate()).
- *-- Usage.......: FLen(<nHandle>)
- *-- Example.....: FLen(6)
- *-- Returns.....: nLength = Length of file in bytes
- *-- Parameters..: nHandle = DOS file handle
- *----------------------------------------------------------------------
-
- parameters nHandle
- private nCurPos, nLength, xJunk
-
- *-- Locate current position in file without moving pointer
- nCurPos = Ftell( m->nHandle )
-
- *-- Find the length of the file by shifting the pointer to the end
- nLength = fseek( m->nHandle, 0, 2 )
-
- *-- Return the pointer to the original starting point
- nJunk = fseek( m->nHandle, m->nCurPos, 0 )
-
- RETURN( m->nLength )
- *-- EoF: FLen()
-
- FUNCTION FReadI32
- *----------------------------------------------------------------------
- *-- Programmer..: Borland
- *-- Date........: 1992
- *-- Notes.......: Convert a 4-byte integer to its decimal value.
- *-- The UDF reads the next 4 bytes from a file and
- *-- converts them to decimal.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: Original
- *-- Calls.......: None
- *-- Called by...: Any (specifically FindTagExp)
- *-- Usage.......: FReadI32(<nHandle>)
- *-- Example.....: FReadI32(4)
- *-- Returns.....: nResult = Decimal value of next 4 bytes in file
- *-- Parameters..: nHandle = DOS file handle
- *----------------------------------------------------------------------
-
- parameters nHandle
- private nResult, nByte1, nByte2, nByte3, nByte4
-
- nResult = 0
- nByte1 = asc( fread( m->nHandle,1 ) )
- nByte2 = asc( fread( m->nHandle,1 ) ) * 256
- nByte3 = asc( fread( m->nHandle,1 ) ) * 256 * 256
- nByte4 = asc( fread( m->nHandle,1 ) ) * 256 * 256 * 256
- nResult = m->nByte1 + m->nByte2 + m->nByte3 + m->nByte4
-
- RETURN (m->nResult)
- *-- EoF: FReadI32()
-
- FUNCTION MDXGaug2
- *-----------------------------------------------------------------------
- *-- Programmer..: Patrick Nelson (CIS: 71042,3445)
- *-- Date........: 11/17/1993
- *-- Notes.......: Indexes a database, showing a fuel-gauge style
- *-- progress indicator during the process. You must SET
- *-- DBTRAP OFF in the calling routine or at the dot
- *-- prompt (or in your CONFIG.DB: DBTRAP=OFF).
- *-- Initially DelMDX() to del the MDX and reference to
- *-- it in the DBF. This routine slows down indexing,
- *-- but the user sees the progress.
- *-- Written for.: dBASE IV ver 1.5
- *-- Rev. History: 04/26/1993 - Original: Rose Vines (CIS: 100026,3153)
- *-- 11/17/1993 - Modified for cross directory access of
- *-- DBF/MDX - and passing of bar colors (PN)
- *-- Calls.......: Gaug2(), DelGauge()
- *-- Called by...: Any
- *-- Usage.......: MDXGaug2("<cDataFile>","<cIndexExp>","<cMTag>",;
- *-- "<cMdxName>","<cClr>","<cClr>","<cClr>",;
- *-- <nURow>,<nLCol>)
- *-- Example.....: x = MDXGaug2("FRED","LNAME+FNAME","FULLNAME","","",;
- *-- "","",0,0)
- *-- Indexes FRED.DBF residing in current directory on
- *-- the last and first names, to the production MDX with
- *-- a tagname of FULLNAME. Uses default colours and
- *-- positions it at 0,0.
- *-- x = MDXGaug2("\APP\DATA\FRED","substr(LNAME,5)",;
- *-- "SHORTNAME","OTHERS","w+/gr,,n/gr",;
- *-- "w+/b","g/g",10,15)
- *-- Indexes FRED.DBF residing in \APP\DATA on 1st 5 char
- *-- of lname to a non-production MDX called OTHERS,
- *-- tagname SHORTNAME. Sets colours of the window and
- *-- fuel-gauge empty & full and positions it starting at
- *-- 10,15.
- *-- Returns.....: nError = 0 if MDX header was updated correctly
- *-- = 1 if MDX header couldn't be updated
- *-- Parameters..: cDataFile = DBF to be indexed. Can be in any
- *-- directory.
- *-- cMdxExpr = Indexing expression
- *-- cMdxTag = Index TAG name
- *-- cMdxName = MDX name - only needed if using a
- *-- non-production MDX.
- *-- cClrBox = Colours for fuel gauge Window. Use basic
- *-- window coloring syntax.
- *-- cClrEmp = Colours for fuel gauge bar empty.
- *-- cClrFul = Colours for fuel gauge bar full.
- *-- nURow = Starting row for the fuel gauge on
- *-- screen. Must be less than 20 - if not,
- *-- the program will make nURow = 19.
- *-- nLCol = Starting column for the fuel gauge.
- *-- Must be less than 26 - if not, the
- *-- program will make nLCol = 25.
- *-----------------------------------------------------------------------
- parameters cDbfName,cMdxExpr,cMdxTag,cMdxName,cClrBox,cClrEmp,;
- cClrFul,nURow,nLCol
- private nBarLen, cBarPad, cIndex, nError, nRecInt, nBarFull
- use (cDbfName) exclusive
- cMdxExpr = upper(cMdxExpr)
- cMdxTag = upper(cMdxTag)
- cCurs = set("CURSOR")
- set cursor off
-
- *-- If colour parameter is blank, use default colour scheme
- if m->cClrBox <> ""
- m->cClrBox = SET("ATTR")
- endif
- if isblank(m->cClrEmp)
- m->cClrEmp = "w+/b"
- endif
- if isblank(m->cClrFul)
- m->cClrFul = "b/b"
- endif
- if m->nURow > 19
- m->nURow = 19
- endif
- if m->nLCol > 25
- m->nLCol = 25
- endif
-
- *-- Determine width of fuel-gauge
- if reccount() > 40
- m->nRecInt = int(reccount()/40)
- m->nBarLen = int( reccount() / m->nRecInt )
- else
- m->nBarLen = reccount() + 1
- endif
- m->cBarPad = space(round((m->nBarLen-16)/3,0))
-
- *-- Display fuel-gauge window and empty gauge
- define window wGauge from m->nURow, m->nLCol to ;
- m->nURow+5,m->nBarLen+m->nLCol+3 ;
- color &cClrBox.
- save screen to sGuage
- do Shadow with m->nURow,m->nLCol,m->nURow+5,m->nBarLen+m->nLCol+3
- activate window wGauge
- @ 0,0 say "Indexing "+dbf()+" For "+cMdxTag
- @ 1,1 say "0% " + m->cBarPad + "25% " + m->cBarPad + "75% " +;
- m->cBarPad + "100%"
- @ 2,1 say replicate( chr(219), m->nBarLen ) color &cClrEmp.
- @ 2,1 say ""
-
- *-- Check if it's a production index or not, and then
- *-- use the appropriate index expression. The FOR condition
- *-- in the expression "fills up" the fuel gauge.
- if "" = m->cMdxName
- index on &cMdxExpr. tag &cMdxTag. for Gaug2(m->cClrFul,m->cClrEmp)
- else
- index on &cMdxExpr. tag &cMdxTag. of &cMdxName. for ;
- Gaug2(m->cClrFul,m->cClrEmp)
- endif
- set color to &cClrBox.
-
- *-- Clean up
- @ 3,1 say "Closing files..." color w+/gr
- nError = 0
- cFlPth = set("FULLPATH")
- set fullpath on
- cIndex = mdx()
- set fullpath &cFlPth.
- use
-
- *-- Call UDF to delete reference to Gaug2() UDF from MDX header
- nError = DelGauge(m->cIndex, m->cMdxTag)
- deactivate window wGauge
- release window wGauge
- restore screen from sGuage
- release screen sGuage
- set cursor &cCurs.
-
- RETURN (nError)
- *-- EoF: MDXGaug2()
-
- FUNCTION Gaug2
- *-----------------------------------------------------------------------
- *-- Programmer..: Patrick Nelson (CIS: 71042,3445)
- *-- Date........: 11/17/93
- *-- Notes.......: Routine used by MDXGaug2() to "fill up" the fuel-gauge
- *-- on screen during indexing.
- *-- It is called from an indexing "FOR" expression, and
- *-- always returns .T. to include all records in the
- *-- index.
- *-- Written for.: dBASE IV, 1.5
- *-- Rev. History: 04/26/1993 - Original: Rose Vines (CIS: 100026,3153)
- *-- 11/17/1993 - Modified for cross directory access of
- *-- DBF/MDX - and passing of bar colors (PN)
- *-- Calls.......: None
- *-- Called by...: MDXGaug2() Function in FILES.PRG
- *-- Usage.......: Gaug2(<cClrFul>,<cClrEmp>)
- *-- Example.....: Gaug2(m->cClrFul,m->cClrEmp)
- *-- Returns.....: .T.
- *-- Parameters..: cClrFul = Color of 'full'
- *-- cClrEmp = Color of 'empty'
- *-----------------------------------------------------------------------
-
- parameters cClrFul,cClrEmp
-
- *-- Every time 2% of the file or so is indexed...
- if reccount() > 40
- if mod( recno(), m->nRecInt ) = 0
- *-- Display a solid bar character to "fill up" the gauge
- set color to &cClrFul.
- ?? chr(219) &&177
- set color to &cClrEmp.
- endif
- else
- set color to &cClrFul.
- ?? chr(219) &&177
- set color to &cClrEmp.
- endif
-
- RETURN (.T.)
- *-- EoF: Gaug2()
-
- FUNCTION NewRec
- *----------------------------------------------------------------------
- *-- Programmer..: Angus Scott-Fleming (CIS: 75500,3223)
- *-- Date........: 05/03/1993
- *-- Notes.......: This will recycle records instead of APPENDING Blank.
- *-- Effectively it recycles "deleted" records, but it
- *-- requires that your routines that delete records
- *-- actually blank them, and do NOT pack the database.
- *-- If no blank records are in the database, the routine
- *-- will append blank. Your delete routines should:
- *-- BLANK the record and
- *-- DELETE the record as well (turn on the delete flag)
- *-- NOTE: This routine assumes you are using a character
- *-- field for your .MDX Tag Expression.
- *-- Written for.: dBASE IV, 1.5 (will work with 1.1, but requires
- *-- that you create a BLANK() routine ...)
- *-- Rev. History: 05/28/1992 -- Original
- *-- 05/03/1993 -- &cTagExpr. correction noted by Zak.
- *-- Calls.......: RecLock() Function in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: NewRec()
- *-- Example.....: IF NewRec()
- *-- replace fields with new data
- *-- ELSE
- *-- error routine
- *-- ENDIF
- *-- Returns.....: Logical -- .T. if new record is locked, .F. if not.
- *-- Parameters..: None
- *----------------------------------------------------------------------
-
- private lOldExact, cTagExpr
-
- lOldExact = set("EXACT")="ON"
- set exact on
- set deleted off
-
- *-- get tag expression for current .MDX tag
- cTagExpr = key(tagno(order()))
-
- *-- look for a blank record, and attempt to lock the record
- if seek(space(len(&cTagExpr.))) .and. rlock()
- recall && turn off deleted flag
- else && no blank records
- append blank && add one
- endif
-
- *-- reset
- set deleted on
- if .not. lOldExact
- set exact off
- endif
-
- RETURN RecLock() && if using 1.1, replace with RLock() internal dBASE
- * function
- *-- EoF: NewRec()
-
- FUNCTION IsNetDir
- *-----------------------------------------------------------------------
- *-- Programmer..: Angus Scott-Fleming (CIS: 75500,3223)
- *-- Date........: 07/14/1993
- *-- Notes.......: Tests for existence of a directory
- *-- NOTE: on Novell Netware 3.11, FILE("Z:\DBASE\NUL")
- *-- always returns .T. even if disk volume Z: is not
- *-- MAPped by the user, or if \DBASE does NOT exist. This
- *-- is a quirk of the interaction between Netware and DOS
- *-- Written for.: dBASE IV v1.5+
- *-- Rev. History: 07/14/1993 first draft
- *-- based on pseudocode by Pat Kennedy, Borland Tech
- *-- Support
- *-- Calls.......: Net_Err Procedure in FILES.PRG
- *-- Called by...: Any
- *-- Usage.......: IsNetDir(<cTestDir>)
- *-- Example.....: if IsNetDir("F:\DBASE\DATA")
- *-- Returns.....: logical .T. if directory is available, .F. if not
- *-- Parameters..: cTestDir = [disk:] and directory to check for
- *-- Side Effect.: Changes ON ERROR setting to nul.
- *-----------------------------------------------------------------------
-
- parameter cTestDir
-
- *-- if parameter is empty, return
- if isblank(m->cTestDir)
- return .F.
- endif
-
- *-- if lNetError does not exist, create it
- if type("lNetError")="U"
- public lNetError
- endif
- m->lNetError = .F.
-
- *-- if there's an error, call routine below
- on error do Net_Err
-
- *-- save current directory settings
- private cOldDir
- cOldDir = set("directory")
-
- *-- change to new directory -- if error, this is where it will
- *-- occur, and routine will be called ...
- set directory to &cTestDir.
-
- *-- cleanup and return to original directory setting
- on error
- set directory to &cOldDir.
-
- RETURN .not. m->lNetError
- *-- EoF: IsNetDir()
-
- PROCEDURE Net_Err
- *-----------------------------------------------------------------------
- *-- Programmer..: Angus Scott-Fleming (CIS: 75500,3223)
- *-- Date........: 07/14/1993
- *-- Notes.......: Routine to handle error processing if a network
- *-- directory doesn't exist. This is part of IsNetDir().
- *-- Written for.: dBASE IV, 1.5 ...
- *-- Rev. History: 07/14/1993 -- Original Release
- *-- Calls.......: None
- *-- Called by...: IsNetDir() Function in FILES.PRG
- *-- Usage.......: On error do Net_Err
- *-- Example.....: ditto.
- *-- Returns.....: None
- *-- Parameters..: None
- *-----------------------------------------------------------------------
-
- do case
- case ERROR() = 413
- * 413 - Not a valid directory:
- lNetError = .T.
- case ERROR() = 412
- * 412 - Not a valid Disk drive:
- lNetError = .T.
- otherwise
- wait "Unknown error: "+str(errno())+" "+errmsg()
- endcase
-
- RETURN
- *-- EoP: Net_Err
-
- *-----------------------------------------------------------------------
- *-- Routines here by courtesy
- *-----------------------------------------------------------------------
-
- PROCEDURE Shadow
- *-----------------------------------------------------------------------
- *-- Programmer..: Ashton-Tate
- *-- Date........: 06/02/1993
- *-- Notes.......: Creates a shadow for a window (taken from the dBASE IV
- *-- picklist functions)
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 05/23/1991 - original procedure.
- *-- 12/14/1991 - Modified by Jim Magnant (TXAGGIE) - to
- *-- check for columns exceeding 79, and temporarily
- *-- change last col. value (so routine doesn't "blow
- *-- up").
- *-- 01/27/1992 -- Modifiedy by Ken Mayer to check for
- *-- bottom of screen, based on what Jim did above. No
- *-- further than 23.
- *-- 06/02/1993 -- Modified to handle screens larger than
- *-- 24 lines. (KJM)
- *-- Calls.......: None
- *-- Called by...: Too many to list ...
- *-- Usage.......: do shadow with <nULRow>,<nULCol>,<nBRRow>,<nBRCol>
- *-- Example.....: save screen to sMain
- *-- activate screen
- *-- define window wError from 5,15 to 15,65 double color;
- *-- rg+/r,rg+/r,rg+/r
- *-- do shadow with 5,15,15,65
- *-- activate window WError
- *-- && perform actions in window
- *-- release window WError
- *-- restore screen from sMain
- *-- release screen sMain
- *-- Returns.....: None
- *-- Parameters..: nULRow = Upper Left Row position
- *-- nULCol = Upper Left Column position (x,y)
- *-- nBRRow = Bottom Right Row position
- *-- nBRCol = Bottom Right Column position (x2,y2)
- *-----------------------------------------------------------------------
-
- parameters nULRow,nULCol,nBRRow,nBRCOL
- private nTempRow,nTempCol,nIncRow,nIncCol,cScreen,nScreen
-
- *-- if screen is larger than 24 lines (EGA43, EGA50 ...)
- m->cScreen = set("DISPLAY")
- if m->cScreen = "MONO"
- m->nScreen = 23
- else
- m->nScreen = val(right(m->cScreen,2))-2
- endif
-
- m->nTempRow = iif(m->nBRRow+1>m->nScreen,m->nScreen,m->nBRRow+1)
- m->nTempCol = iif(m->nBRCol+2>79,79,m->nBRCol+2)
- m->nIncRow = 1
- m->nIncCol = (m->nBRCol-m->nULCol) / (m->nBRRow-m->nULRow)
- do while m->nTempRow <> m->nULRow .or. m->nTempCol <> m->nULCol+2
- m->nRightCol = m->nBRCol
- m->nBRCol = iif(m->nBRCol + 2 > 79,77,m->nBRCol)
- m->nBotRow = m->nBRRow
- m->nBRRow = iif(m->nBRRow + 1 > m->nScreen,m->nScreen-1,m->nBRRow)
- @ m->nTempRow,m->nTempCol fill to m->nBRRow+1,m->nBRCol+2 ;
- color n+/n
- m->nBRCol = m->nRightCol
- m->nBRRow = m->nBotRow
- m->nTempRow = iif(m->nTempRow<>m->nULRow,m->nTempRow -m->nIncRow,;
- m->nTempRow)
- m->nTempCol = iif(m->nTempCol<>m->nULCol+2,m->nTempCol - ;
- m->nIncCol,m->nTempCol)
- m->nTempCol = iif(m->nTempCol<m->nULCol+2,m->nULCol+2,m->nTempCol)
- enddo
-
- RETURN
- *-- EoP: Shadow
-
- *-----------------------------------------------------------------------
- *-- EoP: FILES.PRG
- *-----------------------------------------------------------------------
-